34 lines
1.3 KiB
Python
34 lines
1.3 KiB
Python
"""Релевантность: один фильтр для всех провайдеров, чтобы мусор не лез в базу."""
|
||
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)] |