Features: 1) Add priority field to Brand model to support ranking functionality; 2) Enhance ProductDocument with brand_priority field in Elasticsearch for improved sorting; 3) Integrate function score query with brand_priority in Elasticsearch search logic;

Fixes: None;

Extra: 1) Update migrations for Brand model changes; 2) Refactor Elasticsearch query logic for clarity;
This commit is contained in:
Egor Pavlovich Gorbunov 2025-06-20 05:26:03 +03:00
parent 41b6c1aa07
commit 2840370c3e
4 changed files with 64 additions and 2 deletions

View file

@ -45,7 +45,7 @@ def process_query(query: str = "", request: Request | None = None):
query = query.strip() query = query.strip()
try: try:
q = Q( query_base = Q(
"bool", "bool",
should=[ should=[
Q( Q(
@ -65,9 +65,26 @@ def process_query(query: str = "", request: Request | None = None):
minimum_should_match=1, minimum_should_match=1,
) )
function_score_query = Q(
"function_score",
query=query_base,
functions=[
{
"filter": Q("term", **{"_index": "products"}),
"field_value_factor": {
"field": "brand_priority",
"factor": 1,
"modifier": "log1p",
"missing": 0,
},
}
],
boost_mode="sum",
)
search = ( search = (
Search(index=["products", "categories", "brands", "posts"]) Search(index=["products", "categories", "brands", "posts"])
.query(q) .query(function_score_query)
.extra(size=100) .extra(size=100)
) )
response = search.execute() response = search.execute()

View file

@ -53,6 +53,12 @@ class _BaseDoc(ActiveOnlyMixin, Document):
class ProductDocument(_BaseDoc): class ProductDocument(_BaseDoc):
rating = fields.FloatField(attr="rating") rating = fields.FloatField(attr="rating")
brand_priority = fields.IntegerField(
attr="brand.priority",
null=True,
index=True,
fields={"raw": fields.KeywordField()},
)
class Index(_BaseDoc.Index): class Index(_BaseDoc.Index):
name = "products" name = "products"

View file

@ -0,0 +1,32 @@
# Generated by Django 5.2 on 2025-06-20 02:25
import django_extensions.db.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0026_brand_slug_alter_category_slug_alter_product_slug"),
]
operations = [
migrations.AddField(
model_name="brand",
name="priority",
field=models.PositiveIntegerField(default=0, verbose_name="brand priority"),
),
migrations.AlterField(
model_name="brand",
name="slug",
field=django_extensions.db.fields.AutoSlugField(
allow_unicode=True,
blank=True,
editable=False,
null=True,
populate_from=("name",),
unique=True,
verbose_name="brand slug",
),
),
]

View file

@ -287,6 +287,13 @@ class Brand(ExportModelOperationsMixin("brand"), NiceModel):
unique=True, unique=True,
editable=False, editable=False,
null=True, null=True,
verbose_name=_("brand slug"),
)
priority: int = PositiveIntegerField(
default=0,
null=False,
blank=False,
verbose_name=_("brand priority"),
) )
def __str__(self): def __str__(self):