Fixes: 1) Reduce `_BaseDoc.chunk_size` to prevent potential memory issues. Extra: 1) Disable Elasticsearch parallel indexing to enhance stability.
127 lines
3.6 KiB
Python
127 lines
3.6 KiB
Python
from django_elasticsearch_dsl import Document, fields
|
|
from django_elasticsearch_dsl.registries import registry
|
|
|
|
from core.elasticsearch import COMMON_ANALYSIS, ActiveOnlyMixin, _add_multilang_fields
|
|
from core.models import Brand, Category, Product
|
|
|
|
|
|
class _BaseDoc(ActiveOnlyMixin, Document):
|
|
chunk_size = 200
|
|
|
|
name = fields.TextField(
|
|
attr="name",
|
|
analyzer="standard",
|
|
fields={
|
|
"raw": fields.KeywordField(ignore_above=256),
|
|
"ngram": fields.TextField(
|
|
analyzer="name_ngram", search_analyzer="query_lc"
|
|
),
|
|
"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="query_lc"
|
|
),
|
|
"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(_BaseDoc):
|
|
suggest = fields.CompletionField(
|
|
analyzer="autocomplete",
|
|
search_analyzer="autocomplete_search",
|
|
)
|
|
price = fields.FloatField(attr="price")
|
|
quantity = fields.IntegerField(attr="quantity")
|
|
rating = fields.FloatField(attr="rating")
|
|
|
|
class Index(_BaseDoc.Index):
|
|
name = "products"
|
|
|
|
class Django:
|
|
model = Product
|
|
fields = ["uuid"]
|
|
|
|
def prepare_suggest(self, instance):
|
|
terms = [instance.name]
|
|
if instance.brand:
|
|
terms.append(instance.brand.name)
|
|
terms.append(instance.category.name)
|
|
return {"input": terms, "weight": int(instance.quantity)}
|
|
|
|
|
|
_add_multilang_fields(ProductDocument)
|
|
registry.register_document(ProductDocument)
|
|
|
|
|
|
class CategoryDocument(_BaseDoc):
|
|
class Index(_BaseDoc.Index):
|
|
name = "categories"
|
|
|
|
class Django:
|
|
model = Category
|
|
fields = ["uuid"]
|
|
|
|
|
|
_add_multilang_fields(CategoryDocument)
|
|
registry.register_document(CategoryDocument)
|
|
|
|
|
|
class BrandDocument(ActiveOnlyMixin, Document):
|
|
name = fields.TextField(
|
|
attr="name",
|
|
analyzer="standard",
|
|
fields={
|
|
"raw": fields.KeywordField(ignore_above=256),
|
|
"ngram": fields.TextField(
|
|
analyzer="name_ngram", search_analyzer="query_lc"
|
|
),
|
|
"phonetic": fields.TextField(analyzer="name_phonetic"),
|
|
},
|
|
)
|
|
|
|
class Index:
|
|
name = "brands"
|
|
settings = {
|
|
"number_of_shards": 1,
|
|
"number_of_replicas": 0,
|
|
"analysis": COMMON_ANALYSIS,
|
|
"index": {"max_ngram_diff": 18},
|
|
}
|
|
|
|
class Django:
|
|
model = Brand
|
|
fields = ["uuid"]
|
|
|
|
def prepare_name(self, instance):
|
|
return getattr(instance, "name", "") or ""
|
|
|
|
|
|
registry.register_document(BrandDocument)
|