Improve tax profit search relevance

This commit is contained in:
2026-09-16 22:31:35 +03:00
parent 47d51cd36b
commit 14e86ccdd8
11 changed files with 81 additions and 44 deletions

View File

@@ -23,6 +23,7 @@ LEGAL_FORM_ALIASES = {
},
}
COMPANY_REGISTRATION_DOCUMENTS = (("230044970", 3000), ("667", 2000), ("4", 1000))
TAX_PROFIT_DOCUMENTS = (("112340", 3000),)
def query_variants(language: str, query: str) -> list[str]:
@@ -34,6 +35,26 @@ def query_variants(language: str, query: str) -> list[str]:
return list(dict.fromkeys(variants))
def document_priority_clauses(language: str, documents: tuple[tuple[str, int], ...]) -> list[dict]:
status = {"ru": "Действует", "ky": "Күчүндө"}[language]
return [
{
"constant_score": {
"filter": {
"bool": {
"filter": [
{"term": {"document_code": code}},
{"term": {f"status_{language}": status}},
]
}
},
"boost": boost,
}
}
for code, boost in documents
]
def company_registration_clauses(language: str, query: str) -> list[dict]:
non_registration_context = {
"ru": (r"\bсч[её]т\w*", r"\bбанк\w*", r"\bфилиал\w*", r"\bпредставительств\w*"),
@@ -66,38 +87,28 @@ def company_registration_clauses(language: str, query: str) -> list[dict]:
if not any(re.search(pattern.format(form=forms), normalized_query) for pattern in patterns):
return []
status = {"ru": "Действует", "ky": "Күчүндө"}[language]
# ponytail: curated legal mapping; replace with a reviewed intent catalog when coverage expands.
def clause(document_code: str, boost: int) -> dict:
return {
"constant_score": {
"filter": {
"bool": {
"filter": [
{"term": {"document_code": document_code}},
{"term": {f"status_{language}": status}},
]
}
},
"boost": boost,
}
}
return document_priority_clauses(language, COMPANY_REGISTRATION_DOCUMENTS)
return [clause(code, boost) for code, boost in COMPANY_REGISTRATION_DOCUMENTS]
def tax_profit_clauses(language: str, query: str) -> list[dict]:
if language != "ru" or not re.search(r"\алог\w*\s+(?:на\s+)?прибыл\w*\b", query.casefold()):
return []
# ponytail: exact topic anchor; expand only with verified tax-code sources.
return document_priority_clauses(language, TAX_PROFIT_DOCUMENTS)
def build_search_query(language: str, query: str) -> dict:
intent_clauses = company_registration_clauses(language, query)
registration_clauses = company_registration_clauses(language, query)
intent_clauses = [*registration_clauses, *tax_profit_clauses(language, query)]
operator = "OR" if registration_clauses else "AND"
full_text = [
{
"multi_match": {
"query": variant,
"fields": [f"document_name_{language}^4", f"text_{language}"],
"type": "cross_fields",
"operator": "OR" if intent_clauses else "AND",
}
}
clause
for variant in query_variants(language, query)
for clause in (
{"match": {f"text_{language}": {"query": variant, "operator": operator}}},
{"match": {f"document_name_{language}": {"query": variant, "operator": operator, "boost": 4}}},
{"match_phrase": {f"text_{language}": {"query": variant, "boost": 3}}},
)
]
planned = {"should": [*full_text, *intent_clauses], "minimum_should_match": 1}
return {"bool": planned}