django haystack elasticsearch不会给出正确的结果
问题描述:
我有一个django-haystack elasticsearch的问题。我有一个搜索问题,其中一个字段是study_level,它是1到13的整数。当我尝试进行搜索以将问题包含在10-12范围内时,它还提供了其他study_level的问题。在搜索中,似乎study_level无关紧要。django haystack elasticsearch不会给出正确的结果
我有这个指数
class QuestionIndex(indexes.SearchIndex, indexes.Indexable):
""" A Haystack search index for Questions. """
text = indexes.EdgeNgramField(document=True, use_template=True)
id = indexes.IntegerField(model_attr='id')
user_id = indexes.IntegerField(model_attr='user_id')
question = indexes.EdgeNgramField(model_attr='question', boost=1.15)
study_level = indexes.IntegerField(model_attr='study_level')
is_answered = indexes.IntegerField(model_attr='is_answered')
is_archived = indexes.BooleanField(model_attr='is_archived')
created_at = indexes.DateTimeField(model_attr='created_at')
tags = indexes.MultiValueField()
schools = indexes.MultiValueField()
answers = indexes.IntegerField(indexed=False)
has_answer = indexes.IntegerField(indexed=False)
content = indexes.CharField(indexed=False)
content_short = indexes.CharField(indexed=True)
def get_model(self):
return Question
def prepare_study_level(self, obj):
study_level = obj.study_level
还有更多高清prepare_x但study_level是我的问题。
然后将其在过滤器study_level这个代码后
class QuestionSearch(object):
# Plain old Python object for question search.
MAX_RESULT_LENGTH = 12
def __init__(self, user, query='', limit=MAX_RESULT_LENGTH, subjects=[], study_level_min=None, study_level_max=None):
self.user = user
self.query = query
self.limit = limit
self.subjects = subjects
self.study_level_min = study_level_min
self.study_level_max = study_level_max
# Swaps the min and max values if they are in the wrong order.
if study_level_min and study_level_max and study_level_min > study_level_max:
self.study_level_min = study_level_max
self.study_level_max = study_level_min
self.schools = None # Signal value for the memoization below.
self.search_qs = SearchQuerySet().filter(is_archived=0).models(Question).order_by(
'is_answered', 'has_answer', 'created_at'
)
def search(self, exclude_current_user=False):
if exclude_current_user:
self.search_qs = self.search_qs.exclude(user_id=self.user.id)
# These methods update the search_qs member variable.
self.filter_subjects()
self.filter_schools()
self.filter_query()
self.filter_study_level()
return self.search_qs[:self.limit]
def filter_subjects(self):
if len(self.subjects) > 0:
tag_sq = [SQ(tags__contains=subject) for subject in self.subjects]
tag_query = tag_sq.pop()
for item in tag_sq:
tag_query |= item
self.search_qs = self.search_qs.filter(tag_query)
def filter_schools(self):
# Memoization of schools.
if not self.schools:
self.schools = get_accessible_schools(self.user)
school_ids = [school.id for school in self.schools]
self.search_qs = self.search_qs.filter(schools__in=school_ids)
def filter_query(self):
if self.query != '':
self.search_qs = self.search_qs.filter(
SQ(question__contains=self.query) | SQ(content_short__contains=self.query)
)
def filter_study_level(self):
from redbutton.helpers import init_logger
logger = init_logger()
logger.warning("--------------------------------")
study_levels = self._get_study_level_range()
logger.warning(study_levels)
logger.warning("before filter study_level")
logger.warning(vars(self.search_qs.query))
self.search_qs = self.search_qs.filter(study_level__in=study_levels)
logger.warning("After filter study_level")
logger.warning(vars(self.search_qs.query))
def _get_study_level_range(self):
study_level_min = 1 if not self.study_level_min else self.study_level_min
study_level_max = 12 if not self.study_level_max else self.study_level_max
return range(study_level_min, study_level_max+1)
@classmethod
def get_filter_params(cls, homework_settings):
kwargs = {}
kwargs['schools__in'] = get_accessible_schools(homework_settings.user)
if homework_settings.study_level_min and homework_settings.study_level_max:
kwargs['study_level__in'] = range(homework_settings.study_level_min, homework_settings.study_level_max)
tag_names = list(homework_settings.tags.all().values_list('name', flat=True))
if len(tag_names) > 0:
kwargs['tags__name__in'] = tag_names
return kwargs
@classmethod
def get_study_level_string(cls, study_level):
"""
Parameters:
study_level (string): An string convertible to an int, for the study_level.
Returns:
Valid study_level choice for questions or None.
"""
try:
study_level = int(study_level)
if study_level not in dict(Question.STUDY_LEVEL_CHOICES):
study_level = None
except (TypeError, ValueError):
study_level = None
return study_level
logger.warning(VARS(self.search_qs.query))用于显示
{'_hit_count': None, '_using': u'default', 'distance_point': {}, 'within': {}, 'query_filter': <SQ: AND (is_archived__content=0 AND NOT (user_id__content=4) AND tags__contains=mate AND schools__in=[231L, 231L, 231L, 231L, 4470L, 2029L, 4919L, 4920L] AND study_level__in=[10, 11, 12])>, '_raw_query': None, '_raw_query_params': {}, '_spelling_suggestion': <object object at 0x7ffbdc676ed0>, '_stats': None, 'backend': <search.search_backends.CustomElasticBackend object at 0x7ffbdb64e210>, 'stats': {}, 'order_by': [u'is_answered', u'has_answer', u'created_at'], 'result_class': <class 'haystack.models.SearchResult'>, 'spelling_query': None, 'narrow_queries': set([]), 'boost': {}, 'query_facets': [], 'models': set([<class 'homeworkhelp.models.Question'>]), 'date_facets': {}, 'start_offset': 0, 'end_offset': None, '_more_like_this': False, '_mlt_instance': None, 'fields': [], 'facets': {}, '_facet_counts': None, '_results': None, 'highlight': False, 'dwithin': {}}
这里最重要的部分是AND study_level__in = [10,11,12]
但这里的问题是,最终搜索结果包括具有其它study_level VALU命中es比列表study_levels中。我不明白为什么study_level不在study_levels的问题是结果的一部分。
如果有人认为他们需要一个像问题车型的详细信息,请与我尽量回答,尽我所能。
答
我不会满意的,但它的工作原理似乎工作。
if int(study_level_min) <= item.study_level <= int(study_level_max) and count_added_result <= limit:
result_list.append(class_fields)
count_added_result += 1
if count_added_result > limit:
break
现在给出正确的结果,但它不解决草垛没有给出预期resluts原来的问题,这将有现在要做的。