diff --git a/core/elasticsearch/__init__.py b/core/elasticsearch/__init__.py index 473f93af..d3674193 100644 --- a/core/elasticsearch/__init__.py +++ b/core/elasticsearch/__init__.py @@ -183,6 +183,7 @@ COMMON_ANALYSIS = { }, "query_lc": {"tokenizer": "standard", "filter": ["lowercase", "asciifolding"]}, }, + "normalizer": {"lc": {"type": "custom", "filter": ["lowercase", "asciifolding"]}}, } diff --git a/core/elasticsearch/documents.py b/core/elasticsearch/documents.py index 4a2c895e..ebebc4c5 100644 --- a/core/elasticsearch/documents.py +++ b/core/elasticsearch/documents.py @@ -1,4 +1,4 @@ -from django_elasticsearch_dsl import Document, fields +from django_elasticsearch_dsl import Document, SearchAsYouTypeField, fields from django_elasticsearch_dsl.registries import registry from core.elasticsearch import COMMON_ANALYSIS, ActiveOnlyMixin, _add_multilang_fields @@ -10,7 +10,8 @@ class _BaseDoc(ActiveOnlyMixin, Document): attr="name", analyzer="standard", fields={ - "raw": fields.KeywordField(ignore_above=256), + "raw": fields.KeywordField(ignore_above=256, normalizer="lc"), + "sat": SearchAsYouTypeField(max_shingle_size=4), "ngram": fields.TextField( analyzer="name_ngram", search_analyzer="query_lc" ), @@ -53,6 +54,14 @@ class _BaseDoc(ActiveOnlyMixin, Document): class ProductDocument(_BaseDoc): rating = fields.FloatField(attr="rating") + product_type = fields.KeywordField() + sales_rank = fields.IntegerField() + + def prepare_product_type(self, obj): + return obj.category.slug.split("-")[0] if obj.category else "other" + + def prepare_sales_rank(self, obj): + return obj.total_orders or 0 class Index(_BaseDoc.Index): name = "products" diff --git a/core/models.py b/core/models.py index 81b8bdff..feb21079 100644 --- a/core/models.py +++ b/core/models.py @@ -404,6 +404,12 @@ class Product(ExportModelOperationsMixin("product"), NiceModel): cache.set(cache_key, quantity, 3600) return quantity + @property + def total_orders(self): + return OrderProduct.objects.filter( + order__status="FINISHED", product__uuid=self.uuid + ).count() + class Attribute(ExportModelOperationsMixin("attribute"), NiceModel): is_publicly_visible = True