Revert "Features: 1) Add support for .sat suffix fields in search query with phrase_prefix match; 2) Incorporate lenient fuzzy match and prefix match into a combined query logic; 3) Enhance function_score with additional filtering for better query relevance."

This reverts commit 5efac0d5ff.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-06-20 03:27:44 +03:00
parent d0e7c9e4ec
commit c0a753fa15

View file

@ -30,125 +30,113 @@ SMART_FIELDS = [
"title.ngram^3", "title.ngram^3",
"title.phonetic", "title.phonetic",
"title.auto^4", "title.auto^4",
"name.sat^6",
"title.sat^4",
] ]
def process_query(query: str = "", request: Request | None = None): def process_query(query: str = "", request: Request | None = None):
if not (query := query.strip()): """
Perform a lenient, typotolerant, multiindex search.
* Fulltext with fuzziness for spelling mistakes
* `bool_prefix` for edgengram autocomplete / icontains
"""
if not query:
raise ValueError(_("no search term provided.")) raise ValueError(_("no search term provided."))
sat_match = Q( query = query.strip()
"multi_match",
query=query,
type="phrase_prefix",
fields=[f for f in SMART_FIELDS if ".sat" in f],
)
fuzzy_match = Q(
"multi_match",
query=query,
fields=SMART_FIELDS,
fuzziness="AUTO",
operator="and",
)
prefix_match = Q(
"multi_match",
query=query,
fields=[f for f in SMART_FIELDS if f.endswith(".auto")],
type="bool_prefix",
)
combined = Q(
"bool",
should=[sat_match, fuzzy_match, prefix_match],
minimum_should_match=1,
)
functions = [
{
"filter": Q("prefix", **{"name.raw": query.lower()}),
"weight": 5,
},
{
"gauss": {
"sales_rank": {
"origin": 100,
"scale": 500,
"offset": 0,
"decay": 0.3,
}
},
"weight": 3,
},
]
boosted = Q(
"function_score",
query=combined,
boost_mode="sum",
score_mode="sum",
functions=functions,
)
search = (
Search(index=["products", "categories", "brands", "posts"])
.query(boosted)
.extra(size=100)
)
try: try:
response = search.execute() q = Q(
except NotFoundError: "bool",
raise Http404 should=[
Q(
results = {"products": [], "categories": [], "brands": [], "posts": []} "multi_match",
for hit in response.hits: query=query,
obj_uuid = getattr(hit, "uuid", None) or hit.meta.id fields=SMART_FIELDS,
obj_name = getattr(hit, "name", None) or getattr(hit, "title", None) or "N/A" fuzziness="AUTO",
raw_slug = getattr(hit, "slug", None) or "" operator="and",
obj_slug = ( ),
raw_slug or slugify(obj_name) Q(
if hit.meta.index in {"brands", "categories"} "multi_match",
else raw_slug query=query,
fields=[f for f in SMART_FIELDS if f.endswith(".auto")],
type="bool_prefix",
),
],
minimum_should_match=1,
) )
image_url = None
idx = hit.meta.index
if request: functions = [
if idx == "products": {
"gauss": {
"sales_rank": {
"origin": 100,
"scale": 500,
"offset": 0,
"decay": 0.3,
}
},
"weight": 3,
},
]
boosted = Q(
"function_score",
query=q,
boost_mode="sum",
score_mode="sum",
functions=functions,
)
search = (
Search(index=["products", "categories", "brands", "posts"])
.query(boosted)
.extra(size=100)
)
response = search.execute()
results: dict = {"products": [], "categories": [], "brands": [], "posts": []}
for hit in response.hits:
obj_uuid = getattr(hit, "uuid", None) or hit.meta.id
obj_name = (
getattr(hit, "name", None) or getattr(hit, "title", None) or "N/A"
)
obj_slug = ""
raw_slug = getattr(hit, "slug", None)
if raw_slug:
obj_slug = raw_slug
elif hit.meta.index == "brands":
obj_slug = slugify(obj_name)
elif hit.meta.index == "categories":
obj_slug = slugify(f"{obj_name}")
image_url = None
idx = hit.meta.index
if idx == "products" and request:
prod = get_object_or_404(Product, uuid=obj_uuid) prod = get_object_or_404(Product, uuid=obj_uuid)
first = prod.images.order_by("priority").first() first = prod.images.order_by("priority").first()
image_url = ( if first and first.image:
request.build_absolute_uri(first.image.url) image_url = request.build_absolute_uri(first.image.url)
if first and first.image elif idx == "brands" and request:
else None
)
if idx == "brands":
brand = get_object_or_404(Brand, uuid=obj_uuid) brand = get_object_or_404(Brand, uuid=obj_uuid)
image_url = ( if brand.small_logo:
request.build_absolute_uri(brand.small_logo.url) image_url = request.build_absolute_uri(brand.small_logo.url)
if brand.small_logo elif idx == "categories" and request:
else None
)
if idx == "categories":
cat = get_object_or_404(Category, uuid=obj_uuid) cat = get_object_or_404(Category, uuid=obj_uuid)
image_url = ( if cat.image:
request.build_absolute_uri(cat.image.url) if cat.image else None image_url = request.build_absolute_uri(cat.image.url)
)
results[idx].append( results[idx].append(
{ {
"uuid": str(obj_uuid), "uuid": str(obj_uuid),
"name": obj_name, "name": obj_name,
"slug": obj_slug, "slug": obj_slug,
"image": image_url, "image": image_url,
} }
) )
return results return results
except NotFoundError:
raise Http404
LANGUAGE_ANALYZER_MAP = { LANGUAGE_ANALYZER_MAP = {