product search with ranking is working
This commit is contained in:
@@ -467,8 +467,6 @@ class ProductSearchTest(TestCase):
|
|||||||
self.factory(tags="lunares/azules", description="zapatos rojos"),
|
self.factory(tags="lunares/azules", description="zapatos rojos"),
|
||||||
self.factory(tags="lunares/rojos", description="zapatos"),
|
self.factory(tags="lunares/rojos", description="zapatos"),
|
||||||
self.factory(attributes='"zapatos de campo", tono/oscuro'),
|
self.factory(attributes='"zapatos de campo", tono/oscuro'),
|
||||||
# TODO: workaround for v3 with multi-word tags
|
|
||||||
# self.factory(attributes='zapatos, "zapatos de campo", tono/oscuro'),
|
|
||||||
]
|
]
|
||||||
unexpected_instances = [
|
unexpected_instances = [
|
||||||
self.factory(description="chanclas"),
|
self.factory(description="chanclas"),
|
||||||
@@ -549,18 +547,29 @@ class FindRelatedProductsTest(APITestCase):
|
|||||||
# clear table
|
# clear table
|
||||||
self.model.objects.all().delete()
|
self.model.objects.all().delete()
|
||||||
|
|
||||||
def test_v3_find_by_single_tag(self):
|
def test_v3_find_by_tags(self):
|
||||||
# create tagged product
|
# create tagged product
|
||||||
tag = 'cool'
|
tag = 'cool'
|
||||||
expected_instances = [
|
expected_instances = [
|
||||||
self.factory(tags=tag)
|
self.factory(tags=tag),
|
||||||
|
self.factory(tags=f'{tag} hat'),
|
||||||
|
self.factory(tags=f'temperatures/{tag}'),
|
||||||
|
self.factory(tags=f'temperatures/{tag}, body/hot'),
|
||||||
|
self.factory(tags=f'temperatures/{tag}, hats/{tag}'),
|
||||||
|
# multiple hits
|
||||||
|
self.factory(tags=tag, attributes=tag),
|
||||||
|
self.factory(tags=tag, attributes=tag, category=tag),
|
||||||
|
self.factory(tags=tag, attributes=tag, category=tag, name=tag),
|
||||||
|
self.factory(tags=tag, attributes=tag, category=tag, name=tag, description=tag),
|
||||||
]
|
]
|
||||||
# instance = self.factory()
|
|
||||||
# instance.tags.set(tag)
|
unexpected_instances = [
|
||||||
# instance.save()
|
self.factory(tags="notcool"), # shouldn't catch it
|
||||||
|
self.factory(tags="azules"),
|
||||||
|
]
|
||||||
|
|
||||||
# searh for it
|
# searh for it
|
||||||
results = find_related_products_v3(tag)
|
results = find_related_products_v3(tag)
|
||||||
import ipdb; ipdb.set_trace()
|
|
||||||
|
|
||||||
# assert result
|
# assert result
|
||||||
self.assertTrue(len(results) == len(expected_instances))
|
self.assertTrue(len(results) == len(expected_instances))
|
||||||
@@ -568,3 +577,4 @@ class FindRelatedProductsTest(APITestCase):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,25 +114,21 @@ def find_related_products_v3(keyword):
|
|||||||
SearchVectors for the fields
|
SearchVectors for the fields
|
||||||
SearchQuery for the value
|
SearchQuery for the value
|
||||||
SearchRank for relevancy scoring and ranking
|
SearchRank for relevancy scoring and ranking
|
||||||
|
|
||||||
PROBLEM: returns unrelated instances
|
|
||||||
"""
|
"""
|
||||||
# TODO: figure out why it includes unrelated instances
|
|
||||||
# fields=('name', 'description', 'tags__label', 'attributes__label', 'category__name')
|
|
||||||
|
|
||||||
vector = SearchVector('name') + SearchVector('description') + SearchVector('tags__label') + SearchVector('attributes__label') + SearchVector('category__name')
|
vector = SearchVector('name') + SearchVector('description') + SearchVector('tags__label') + SearchVector('attributes__label') + SearchVector('category__name')
|
||||||
query = SearchQuery(keyword)
|
query = SearchQuery(keyword)
|
||||||
|
|
||||||
products_qs = Product.objects.annotate(
|
products_qs = Product.objects.annotate(
|
||||||
rank=SearchRank(vector, query)
|
rank=SearchRank(vector, query)
|
||||||
).filter(rank__gt=0.05).order_by('-rank')
|
).filter(rank__gt=0.05) # removed order_by because its lost in casting
|
||||||
|
|
||||||
return set(products_qs)
|
return set(products_qs)
|
||||||
|
|
||||||
|
|
||||||
def find_related_products_v4(keyword):
|
def find_related_products_v4(keyword):
|
||||||
"""
|
"""
|
||||||
Using trigrams
|
Similarity-ranked search using trigrams
|
||||||
|
Not working
|
||||||
"""
|
"""
|
||||||
# fields=('name', 'description', 'tags__label', 'attributes__label', 'category__name')
|
# fields=('name', 'description', 'tags__label', 'attributes__label', 'category__name')
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from companies.models import Company
|
|||||||
from history.models import HistorySync
|
from history.models import HistorySync
|
||||||
|
|
||||||
from back_latienda.permissions import IsCreator
|
from back_latienda.permissions import IsCreator
|
||||||
from .utils import extract_search_filters, find_related_products_v5, find_related_products_v4, find_related_products_v3
|
from .utils import extract_search_filters, find_related_products_v3
|
||||||
from utils.tag_serializers import TaggitSerializer
|
from utils.tag_serializers import TaggitSerializer
|
||||||
from utils.tag_filters import ProductTagFilter
|
from utils.tag_filters import ProductTagFilter
|
||||||
|
|
||||||
@@ -155,9 +155,7 @@ def product_search(request):
|
|||||||
chunks = query_string.split(' ')
|
chunks = query_string.split(' ')
|
||||||
|
|
||||||
for chunk in chunks:
|
for chunk in chunks:
|
||||||
product_set = find_related_products_v5(chunk)
|
product_set = find_related_products_v3(chunk)
|
||||||
# product_set = find_related_products_v4(chunk)
|
|
||||||
# product_set = find_related_products_v3(chunk)
|
|
||||||
# add to result set
|
# add to result set
|
||||||
result_set.update(product_set)
|
result_set.update(product_set)
|
||||||
# TODO: add search for entire phrase
|
# TODO: add search for entire phrase
|
||||||
@@ -166,6 +164,7 @@ def product_search(request):
|
|||||||
filters = extract_search_filters(result_set)
|
filters = extract_search_filters(result_set)
|
||||||
# serialize and respond
|
# serialize and respond
|
||||||
product_serializer = ProductSearchSerializer(result_set, many=True, context={'request': request})
|
product_serializer = ProductSearchSerializer(result_set, many=True, context={'request': request})
|
||||||
|
# TODO: send product data in order by rank value
|
||||||
return Response(data={"filters": filters, "products": product_serializer.data})
|
return Response(data={"filters": filters, "products": product_serializer.data})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Response({"errors": {"details": str(e)}}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
return Response({"errors": {"details": str(e)}}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|||||||
Reference in New Issue
Block a user