Django Haystack自动查询:HAYSTACK_DEFAULT_OPERATOR ='AND'没有结果

Ane*_*pic 2 django-haystack elasticsearch

(更新:问题特定于自动查询的使用)

据我从文档以及从源代码可以看出,该HAYSTACK_DEFAULT_OPERATOR设置应控制.filter(...)在查询集上链接子句时如何组合子句。

但是当我AutoQuery额外使用时,似乎正在控制所有单词是否匹配,或者短语中的任何单词都匹配。(我正在使用ElasticSearch)

例如:

HAYSTACK_DEFAULT_OPERATOR = 'OR'
sqs = SearchQuerySet().filter(content=AutoQuery('some of these words are in my content'))
sqs.count() = 53

HAYSTACK_DEFAULT_OPERATOR = 'AND'
sqs = SearchQuerySet().filter(content=AutoQuery('some of these words are in my content'))
sqs.count() = 0
sqs = SearchQuerySet().filter(content=AutoQuery('all these words are in the content'))
sqs.count() = 1
Run Code Online (Sandbox Code Playgroud)

奇怪的是,使用filter_orfilter_and似乎没有任何区别。例如

HAYSTACK_DEFAULT_OPERATOR = 'AND'
sqs = SearchQuerySet().filter_or(content=AutoQuery('some of these words are in my content'))
sqs.count() = 0
Run Code Online (Sandbox Code Playgroud)

答案必须在干草堆源代码中的某个地方,我将继续寻找,至少在文档中这似乎是一个缺陷。

这应该发生吗?有没有办法链接默认为AND的过滤器,同时仍匹配自动查询中的任何单词?

Sev*_*ins 5

很不幸的是,不行。自动查询的部分目的是将查询按单词分开,并使每个单词成为一个单独的查询。它用于执行此操作的运算符取决于您的HAYSTACK_DEFAULT_OPERATOR设置,这是使用它的最重要的原因之一(据我所知,HAYSTACK_DEFAULT_OPERATOR是影响用于自动查询的运算符的唯一方法)。

当您添加filter_or时,所有发生的事情是您的AND链被包裹在OR中。当AND为默认运算符时,filter_or对于将多个过滤器查询链接在一起很有用,但是在这种情况下,它不会执行您期望的操作。

我遇到了类似的问题,而最终击败它的方法是自己实施。您可以使用解析器库(我登陆shlex,该Python库用于解析shell字符串,因为它会将引号内的内容视为单个标记),然后使用它来构造自己的自动查询。

sqs = SearchQuerySet()
sq = None
keywords = 'some of these words are in my content'
for phrase in shlex.split(keywords):
    if not sq:
        sq = SQ(content=phrase)
    else:
        sq |= SQ(content=phrase)
sqs = sqs.filter(sq)
Run Code Online (Sandbox Code Playgroud)

用| =(或运算符)修改SQ将使SQ对象链以OR作为运算符生成结果调用。您也可以将&=用于链接的AND。

另外,一旦使用了SQ对象进行过滤,就可以做任何您想做的事情。如果您的默认运算符为AND,则您在SQ对象上的过滤器之后链接的所有过滤器将为AND过滤器。或者,您可以使用double_double来指定应该将特定过滤器与查询进行AND运算。