solr 中非或查询的 magic
提问:在 solr 中进行非查询的 query 是写作 -field:value
,或查询的 query 是写作 field:value1 OR field:value2
,那么,对同一字段进行多次非或的查询应该如何写呢?
……
从直觉上来说应该是写作 -field:value1 OR -field:value2
,这么是没问题并且也是可以检索出数据的,但是如果加上其他的条件比如 (-field:value1 OR -field:value2) AND other_or_some_field:value3
这样的话,这样是检索不出来数据的,why??
原因请看 Negative Query Problems 这个 solr 官方的 wiki,上面说这是『Solr Magic』哦,而不是个 bug 哦,好吧。。。
解决方法:多查询条件下,在非查询的前面添加全量查询即可,即 ((*:* AND -field:value1) OR (*:* AND -field:value2)) AND other_field:value3
。而 (-field:value1 OR -field:value2)
这个条件跟 -(field:value1 AND field:value2)
其实是等效的逻辑,所以进一步可改写成 (*:* AND -(field:value1 AND field:value2)) AND other_field:value3
。也就是说,多条件的情况下,非或条件要写成 (*:* AND -field:value)
这样的形式,并且如果可以的话尽量把非或条件写到最后以避免出现这个 magic。
如果情况允许的话,可以把查询条件用 fq
来进行查询。
……
然后就是,如果用到了 spring-data-solr
来进行 solr 查询的话,(*:* AND -field:value)
的写法如下
1 | Criteria criteria = Criteria.where(field).is(value); |
也就是说,先用 notOperator()
方法给 criteria 用 -()
给包起来,然后跟 *:*
与结合之后,用 connect()
方法把该次查询加上括号。最后加上括号是为了跟其他条件进行拼接,这对括号的本身并不影响查询。
然后就是多个条件的非或查询比如 (*:* AND -(field:value1 AND field:value2))
的写法如下
1 | Criteria criteria = Criteria.where(field).is(value1); |
This’s “Solr Magic” with negative queries。