product search with ranking is working

This commit is contained in:
Sam
2021-02-19 11:20:03 +00:00
parent 8abcda74f8
commit e31c64eea8
3 changed files with 24 additions and 19 deletions

View File

@@ -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):

View File

@@ -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')

View File

@@ -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)