[英]Django-Haystack not returning exact query
I'm trying to fix my Django-haystack combined with Elasticsearch search results to be exact. 我正在努力修复我的Django-haystack和Elasticsearch搜索结果。
The problem I have now is that when a user try for example, the "Mexico" query, the search results also returns deals in "Melbourne" which is far from being user-friendly. 我现在遇到的问题是,当用户尝试例如“墨西哥”查询时,搜索结果也会返回“墨尔本”中的交易,这远非用户友好。
Anyone can help me to fix this problem? 有人可以帮我解决这个问题吗?
This is what I've tried so far but no good results: 这是我到目前为止尝试过但没有好结果:
My forms.py 我的forms.py
from haystack.forms import FacetedSearchForm
from haystack.inputs import Exact
class FacetedProductSearchForm(FacetedSearchForm):
def __init__(self, *args, **kwargs):
data = dict(kwargs.get("data", []))
self.ptag = data.get('ptags', [])
self.q_from_data = data.get('q', '')
super(FacetedProductSearchForm, self).__init__(*args, **kwargs)
def search(self):
sqs = super(FacetedProductSearchForm, self).search()
# Ideally we would tell django-haystack to only apply q to destination
# ...but we're not sure how to do that, so we'll just re-apply it ourselves here.
q = self.q_from_data
sqs = sqs.filter(destination=Exact(q))
print('should be applying q: {}'.format(q))
print(sqs)
if self.ptag:
print('filtering with tags')
print(self.ptag)
sqs = sqs.filter(ptags__in=[Exact(tag) for tag in self.ptag])
return sqs
My search_indexes.py 我的search_indexes.py
import datetime
from django.utils import timezone
from haystack import indexes
from haystack.fields import CharField
from .models import Product
class ProductIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.EdgeNgramField(
document=True, use_template=True,
template_name='search/indexes/product_text.txt')
title = indexes.CharField(model_attr='title')
description = indexes.EdgeNgramField(model_attr="description")
destination = indexes.EdgeNgramField(model_attr="destination") #boost=1.125
link = indexes.CharField(model_attr="link")
image = indexes.CharField(model_attr="image")
# Tags
ptags = indexes.MultiValueField(model_attr='_ptags', faceted=True)
# for auto complete
content_auto = indexes.EdgeNgramField(model_attr='destination')
# Spelling suggestions
suggestions = indexes.FacetCharField()
def get_model(self):
return Product
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(timestamp__lte=timezone.now())
My models.py 我的models.py
class Product(models.Model):
destination = models.CharField(max_length=255, default='')
title = models.CharField(max_length=255, default='')
slug = models.SlugField(unique=True, max_length=255)
description = models.TextField(max_length=2047, default='')
link = models.TextField(max_length=500, default='')
ptags = TaggableManager()
image = models.ImageField(max_length=500, default='images/zero-image-found.png')
timestamp = models.DateTimeField(auto_now=True)
def _ptags(self):
return [t.name for t in self.ptags.all()]
def get_absolute_url(self):
return reverse('product',
kwargs={'slug': self.slug})
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.title)
super(Product, self).save(*args, **kwargs)
def __str__(self):
return self.destination
And what I have in my views.py 我在views.py中有什么
from haystack.generic_views import FacetedSearchView as BaseFacetedSearchView
from .forms import FacetedProductSearchForm
class FacetedSearchView(BaseFacetedSearchView):
form_class = FacetedProductSearchForm
facet_fields = ['ptags']
template_name = 'search_result.html'
paginate_by = 30
context_object_name = 'object_list'
Thank you. 谢谢。
I just found the solution to this problem. 我刚刚找到了解决这个问题的方法。 Please listen up if you want to avoid loosing any of you reputations by placing a bounty on the same problem.
如果你想通过在同一个问题上放置赏金来避免失去任何声誉,请聆听。
Basically I had to replace my original destination
field in my search_indexes.py document to the following line: 基本上我必须将search_indexes.py文档中的原始
destination
字段替换为以下行:
From this: destination = indexes.EdgeNgramField(model_attr="destination")
由此:
destination = indexes.EdgeNgramField(model_attr="destination")
To this: destination = indexes.CharField(model_attr="destination")
对此:
destination = indexes.CharField(model_attr="destination")
Your issue is in your use of dict.get
您的问题在于您使用
dict.get
self.q_from_data = data.get('q', [''])[0]
For example 例如
data.get('q') # This will return the string "Mexico"
data.get('q')[0] # This will return the first letter "M"
The line should be 这条线应该是
self.q_from_data = data.get('q', '')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.