在solr查询中使用OR和NOT

sto*_*kes 81 lucene search solr

我正在处理类似于以下的solr查询:

((myField:superneat AND myOtherField:somethingElse) OR NOT myField:superneat)
Run Code Online (Sandbox Code Playgroud)

运行此时,不会返回任何结果.使用OR NOT任一侧的标准会返回我期望的结果 - 它们只是不能很好地协同工作.在myField匹配superneat的情况下,我还打算确保将myOtherField设置为somethingElse,但如果myField不是superneat,则将其包含在结果中.

有人能解释为什么solr没有返回这种查询的结果吗?是否应该以某种方式重构查询 - 或者是否有不同的方法可以使用solr来实现所需的结果?

Mau*_*fer 82

我不知道为什么这不起作用,但这个在逻辑上是等价的,它确实有效:

-(myField:superneat AND -myOtherField:somethingElse)
Run Code Online (Sandbox Code Playgroud)

也许它与在查询中定义两次相同的字段有关...

尝试在solr-user组中询问,然后在这里回复最终答案!

  • 请注意,`-myField:superneat或myOtherField:somethingElse`也是相同的,并且稍微简单一些. (8认同)
  • @YorickSijsling的观点是,即使在逻辑上等价,Solr有时也不能很好地处理纯粹的否定查询,例如OP发布的或您发布的查询. (3认同)

小智 39

Instead of "NOT [condition]" use "(*:* NOT [condition])"
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢!即使对于复杂的查询,这个方法也对我有用,而 -(myField:superneat AND -myOtherField:somethingElse) 方法 - 没有! (2认同)

Yon*_*nik 33

Solr当前检查"纯阴性"查询并插入*:*(匹配所有文档)以使其正常工作.

-foo 被solr转化为 (*:* -foo)

最大的警告是,Solr只检查顶级查询是否是纯粹的否定查询!因此,这意味着类似的查询bar OR (-foo)不会更改,因为纯否定查询位于顶级查询的子子句中.您需要自己将此查询转换为bar OR (*:* -foo)

您可以检查solr查询说明以验证查询转换:

?q=-title:foo&debug=query
Run Code Online (Sandbox Code Playgroud)

变成了

(+(-title:foo +MatchAllDocsQuery(*:*))
Run Code Online (Sandbox Code Playgroud)


RMo*_*sey 24

在这里,在Solr文档和另一个SO问题中汇总来自几个不同答案的评论,我发现以下语法为我的用例生成了正确的结果

(my_field = my_value或my_field为null):

(my_field:"my_value" OR (*:* NOT my_field:*))
Run Code Online (Sandbox Code Playgroud)

这适用于solr 4.1.0.这与OP中的用例略有不同; 但是,我认为其他人会发现它很有用.


sto*_*kes 8

您可以在solr用户填写列表中找到solr-user组的后续 操作

流行的想法是NOT运算符可能只用于从查询中删除结果 - 而不仅仅是从整个数据集中排除事物.我碰巧喜欢你建议mausch的语法 - 谢谢!


小智 5

只是为了添加另一个意外情况,这里是未返回预期结果的查询:

*:* AND ( ( field_a:foo AND field_b:bar ) OR !field_b:bar )
Run Code Online (Sandbox Code Playgroud)

field_b就我而言,这是我执行分面的内容,并且需要仅针对该类型(栏)定位查询术语“foo”

我必须在 or 条件之后插入另一个 *:*才能使其正常工作,如下所示:

*:* AND ( ( field_a:foo AND field_b:bar ) OR ( *:* AND !field_b:bar ) )
Run Code Online (Sandbox Code Playgroud)

编辑:这是在 solr 6.6.3 中