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原来的问题,这将有现在要做的。