From bc57cb82fee55d8a2cfccbd0c43ce3c3b3c63b8c Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Fri, 25 Sep 2026 08:52:45 +0300 Subject: [PATCH 1/8] fix: relax content search for long queries --- backend/README.md | 4 +-- backend/search/api.py | 2 +- backend/search/minjust_opensearch.py | 2 +- backend/search/query.py | 37 ++++++++++++++++++++++++++-- backend/search/review.html | 2 +- backend/test_search_relevance.py | 23 +++++++++++++++++ 6 files changed, 63 insertions(+), 7 deletions(-) diff --git a/backend/README.md b/backend/README.md index 9713de9..63b5bda 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,6 +1,6 @@ # Backend Акылдаш -Версия: `0.10.3` +Версия: `0.10.4` Первая backend-область проекта — загрузка правовых документов из официального Open Data API ЦБД Минюста Кыргызской Республики. Код расположен в @@ -240,4 +240,4 @@ PYTHONPATH=backend python3 -m search.query "ЖЧК ачуу тартиби" --la --- -Акылдаш · Backend v0.10.3 · Frontend — не создан +Акылдаш · Backend v0.10.4 · Frontend — не создан diff --git a/backend/search/api.py b/backend/search/api.py index 7659d50..70c2e4a 100644 --- a/backend/search/api.py +++ b/backend/search/api.py @@ -17,7 +17,7 @@ from search.reviews import ReviewSnapshots, ReviewStore API_VERSION = "v1" -SEARCH_ALGORITHM_VERSION = "search-5" +SEARCH_ALGORITHM_VERSION = "search-6" LANGUAGES = {"ru", "ky"} CODE = re.compile(r"^[0-9]+$") MAX_PAGE_SIZE = 100 diff --git a/backend/search/minjust_opensearch.py b/backend/search/minjust_opensearch.py index fa8f9a4..7e3f841 100644 --- a/backend/search/minjust_opensearch.py +++ b/backend/search/minjust_opensearch.py @@ -17,7 +17,7 @@ from typing import Iterator from search.catalog import authority_codes, legal_force_code, source_code -APP_VERSION = "0.10.3" +APP_VERSION = "0.10.4" LANGUAGES = {"ru", "ky"} DEFAULT_MAPPING = Path(__file__).with_name("minjust-fragments-index.json") diff --git a/backend/search/query.py b/backend/search/query.py index 40690e9..685c1eb 100644 --- a/backend/search/query.py +++ b/backend/search/query.py @@ -24,6 +24,18 @@ LEGAL_FORM_ALIASES = { } COMPANY_REGISTRATION_DOCUMENTS = (("230044970", 3000), ("667", 2000), ("4", 1000)) TAX_PROFIT_DOCUMENTS = (("112340", 3000),) +BOILERPLATE_PREFIXES = { + "ru": ("как регулируется", "правовое регулирование", "судебная практика", "сроки и ответственность"), + "ky": (), +} + + +def relaxed_query_text(language: str, query: str) -> str: + value = query.strip() + for prefix in BOILERPLATE_PREFIXES[language]: + if value.casefold().startswith(prefix): + return value[len(prefix):].strip() + return value def query_variants(language: str, query: str) -> list[str]: @@ -100,6 +112,7 @@ def tax_profit_clauses(language: str, query: str) -> list[dict]: def build_search_query(language: str, query: str) -> dict: registration_clauses = company_registration_clauses(language, query) intent_clauses = [*registration_clauses, *tax_profit_clauses(language, query)] + variants = query_variants(language, query) full_text = [ { "multi_match": { @@ -109,13 +122,33 @@ def build_search_query(language: str, query: str) -> dict: "operator": "OR" if registration_clauses else "AND", } } - for variant in query_variants(language, query) + for variant in variants ] + relaxed_text = [] + if not registration_clauses: + seen_relaxed = set() + for variant in variants: + value = relaxed_query_text(language, variant) + words = value.split() + if value in seen_relaxed or len(words) < 2 or (value == variant.strip() and len(words) < 3): + continue + if len(words) < 3 and not any(len(word) >= 5 for word in words): + continue + seen_relaxed.add(value) + relaxed_text.append({ + "multi_match": { + "query": value, + "fields": [f"document_name_{language}^4", f"text_{language}"], + "type": "cross_fields", + "operator": "OR", + "boost": 0.1, + } + }) phrase_matches = [ {"match_phrase": {f"text_{language}": {"query": variant, "boost": 3}}} for variant in query_variants(language, query) ] - planned = {"should": [*full_text, *phrase_matches, *intent_clauses], "minimum_should_match": 1} + planned = {"should": [*full_text, *phrase_matches, *relaxed_text, *intent_clauses], "minimum_should_match": 1} return {"bool": planned} diff --git a/backend/search/review.html b/backend/search/review.html index f5d4316..4ac1cf1 100644 --- a/backend/search/review.html +++ b/backend/search/review.html @@ -117,7 +117,7 @@

Документ

Короткое знакомство

- +