Django + Haystack + ElasticSearch高级查找

时间:2014-08-23 16:59:19

标签: python django elasticsearch django-haystack

我在使用SQ,对象解决Haystack查询方面遇到了麻烦。如果我使用Django ORM及其Q对象执行相同的查询,一切正常。

自从Haystach documentation states that SQ objects are similar to Q ones.以来,我无法弄清楚我在这里做错了什么。我们非常感谢任何帮助。谢谢!

这是我的代码:

class PublicationSearch(object):


    def __init__(self, search_data):
        self.__dict__.update(search_data)


    def search_all_words(self, sq):

        if self.all_words:
            words = self.all_words.split()
            title_sq = SQ()
            full_text_sq = SQ()

            for word in words:
                title_sq = title_sq | SQ(title__icontains=word)
                full_text_sq = full_text_sq | SQ(full_text__icontains=word)
            keyword_sq = title_sq | full_text_sq
            sq = sq & keyword_sq

        return sq


class AdvancedPublicationForm(AdvancedPublicationBaseForm):


    def search(self):

        cleaned_data = super(AdvancedPublicationForm, self).clean()

        # if no query word was submitted, return an empty sqs
        if not any(cleaned_data.itervalues()):
            return self.no_query_found()

        results = self.build_results(cleaned_data)

        return results


    def build_results(self, search_data):

        sq = SQ()
        results = None
        searcher = PublicationSearch(search_data)

        for key in search_data.iterkeys():
            dispatch = getattr(searcher, 'search_%s' % key)
            sq = dispatch(sq)

        if sq and len(sq):
            results = SearchQuerySet().models(Publication).add(sq)

        else:
            results = []
        return results

对两个单词样本的查询如下所示:

(AND: (OR: (AND: ), ('title__icontains', u'casamento'), ('title__icontains', u'civil'), (AND: ), ('full_text__icontains', u'casamento'), ('full_text__icontains', u'civil')))

错误返回:

Failed to query Elasticsearch using '( OR title:(casamento) OR title:(civil) OR  OR full_text:(casamento) OR full_text:(civil))'

1 个答案:

答案 0 :(得分:0)

我设法找到方法。重构看起来如下。

title_sq.add(SQ(title__icontains=word), SQ.OR)
full_text_sq.add(SQ(full_text__icontains=word), SQ.OR)