omni-parse: 12 провайдеров, sqlite+fts5, simhash-дедуп, фильтр релевантности
This commit is contained in:
34
omni/filter.py
Normal file
34
omni/filter.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""Релевантность: один фильтр для всех провайдеров, чтобы мусор не лез в базу."""
|
||||
import re
|
||||
|
||||
STOP = {"without", "2026", "2025", "how", "the", "and", "for", "with", "without", "free", "best"}
|
||||
|
||||
|
||||
def tokens(query):
|
||||
return [t for t in re.findall(r"[\w\-]{3,}", (query or "").lower()) if t not in STOP]
|
||||
|
||||
|
||||
def _has(tok, body):
|
||||
"""Матч с учётом русской морфологии: сравниваем по 5-символьному префиксу."""
|
||||
if tok in body:
|
||||
return True
|
||||
stem = tok[:5] if len(tok) > 5 else tok[:4]
|
||||
return len(stem) >= 4 and stem in body
|
||||
|
||||
|
||||
def relevance(query, item, min_cov=0.6):
|
||||
"""True, если запрос реально покрыт текстом: и в заголовке есть хоть один термин."""
|
||||
toks = tokens(query)
|
||||
if not toks:
|
||||
return True
|
||||
title = (item.title or "").lower()
|
||||
body = title + " " + (item.text or "").lower()
|
||||
hit = sum(1 for t in toks if _has(t, body))
|
||||
title_hit = sum(1 for t in toks if _has(t, title))
|
||||
if len(toks) == 1:
|
||||
return hit == 1
|
||||
return hit >= max(2, int(len(toks) * min_cov + 0.5)) and title_hit >= 1
|
||||
|
||||
|
||||
def apply(query, items, min_cov=0.6):
|
||||
return [i for i in items if relevance(query, i, min_cov)]
|
||||
Reference in New Issue
Block a user