schon/core/elasticsearch/documents.py
Egor fureunoir Gorbunov 0a375ad0d1 Features: 1) Add brand_name and category_name fields to ProductDocument for enhanced search indexing; 2) Introduce expanded ICU-based analyzers for multi-language support, including Arabic, Indic, and CJK; 3) Enable search enhancements with revised weights in SMART_FIELDS and additional language-specific query mappings.
Fixes: 1) Correct typo in total_orders field name in ProductDocument; 2) Replace outdated query_lc analyzer with icu_query for consistent Unicode handling; 3) Remove unnecessary get_object_or_404 calls to optimize batch query performance.

Extra: Refactor process_query function with clearer structure and batch-loading logic; streamline brand and category field handling across documents; improve reboot scripts to rebuild search index automatically.
2025-08-20 05:36:55 +03:00

136 lines
4.1 KiB
Python

from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from health_check.db.models import TestModel
from core.elasticsearch import COMMON_ANALYSIS, ActiveOnlyMixin, _add_multilang_fields
from core.models import Brand, Category, Product
class _BaseDoc(Document):
name = fields.TextField(
attr="name",
analyzer="standard",
fields={
"raw": fields.KeywordField(ignore_above=256),
"ngram": fields.TextField(analyzer="name_ngram", search_analyzer="icu_query"),
"phonetic": fields.TextField(analyzer="name_phonetic"),
"auto": fields.TextField(analyzer="autocomplete", search_analyzer="autocomplete_search"),
},
)
description = fields.TextField(
attr="description",
analyzer="standard",
fields={
"raw": fields.KeywordField(ignore_above=256),
"ngram": fields.TextField(analyzer="name_ngram", search_analyzer="icu_query"),
"phonetic": fields.TextField(analyzer="name_phonetic"),
"auto": fields.TextField(analyzer="autocomplete", search_analyzer="autocomplete_search"),
},
)
slug = fields.KeywordField(attr="slug", index=False)
class Index:
settings = {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": COMMON_ANALYSIS,
"index": {"max_ngram_diff": 20},
}
def prepare_name(self, instance):
return getattr(instance, "name", "") or ""
def prepare_description(self, instance):
return getattr(instance, "description", "") or ""
class ProductDocument(ActiveOnlyMixin, _BaseDoc):
rating = fields.FloatField(attr="rating")
total_orders = fields.IntegerField(attr="total_orders")
brand_priority = fields.IntegerField(
attr="brand.priority",
index=True,
fields={"raw": fields.KeywordField()},
)
category_priority = fields.IntegerField(
attr="category.priority",
index=True,
fields={"raw": fields.KeywordField()},
)
brand_name = fields.TextField(
attr="brand.name",
analyzer="standard",
fields={
"raw": fields.KeywordField(ignore_above=256),
"ngram": fields.TextField(analyzer="name_ngram", search_analyzer="icu_query"),
"phonetic": fields.TextField(analyzer="name_phonetic"),
"auto": fields.TextField(analyzer="autocomplete", search_analyzer="autocomplete_search"),
},
)
category_name = fields.TextField(
attr="category.name",
analyzer="standard",
fields={
"raw": fields.KeywordField(ignore_above=256),
"ngram": fields.TextField(analyzer="name_ngram", search_analyzer="icu_query"),
"phonetic": fields.TextField(analyzer="name_phonetic"),
"auto": fields.TextField(analyzer="autocomplete", search_analyzer="autocomplete_search"),
},
)
class Index(_BaseDoc.Index):
name = "products"
class Django:
model = Product
fields = ["uuid"]
_add_multilang_fields(ProductDocument)
registry.register_document(ProductDocument)
class CategoryDocument(ActiveOnlyMixin, _BaseDoc):
priority = fields.IntegerField(attr="priority")
class Index(_BaseDoc.Index):
name = "categories"
class Django:
model = Category
fields = ["uuid"]
_add_multilang_fields(CategoryDocument)
registry.register_document(CategoryDocument)
class BrandDocument(ActiveOnlyMixin, _BaseDoc):
priority = fields.IntegerField(attr="priority")
class Index(_BaseDoc.Index):
name = "brands"
class Django:
model = Brand
fields = ["uuid"]
_add_multilang_fields(BrandDocument)
registry.register_document(BrandDocument)
class TestModelDocument(Document):
class Index:
name = "testmodels"
class Django:
model = TestModel
fields = ["title"]
ignore_signals = True
related_models: list = []
auto_refresh = False
registry.register_document(TestModelDocument)