Lucene中的-和NOT操作符有什么区别?

t9aqgxwy  于 2022-11-07  发布在  Lucene
关注(0)|答案(3)|浏览(245)

query syntax of Lucene中它表示如下:

The NOT operator excludes documents that contain the term after NOT.
...
The "-" or prohibit operator excludes documents that contain 
the term after the "-" symbol

我认为不同的是-运算符可以单独使用,而NOT则不是这样,是吗?

vmdwslir

vmdwslir1#

有一个非常微妙的区别。看看"Getting a Better Understanding of Lucene's Search Operators"上的这个长线程,它应该有希望回答你的问题。

rjjhvcjd

rjjhvcjd2#

快速回答:

-(禁止)操作符和NOT操作符的行为没有区别,我认为文档没有特别清楚地说明这一点。
这里,NOT-的同义词。
这可以通过一些测试来证明,总结如下。
另请参阅本答案末尾的摘要,它对Lucene经典查询解析器的各个要点进行了很好的提炼。
也许最重要的一点是,ANDORNOT操作符与“传统的”布尔操作符不同。它们有细微的不同。这是因为Lucene的经典查询解析器只是部分依赖于布尔操作--具体来说,文档是否应该得到分数。除此之外,可以以明显“非布尔”的方式来使用运算符,以影响如何相对于彼此对文档进行评分。
考虑到Lucene的目的是 * 按照相关性的顺序 * 显示结果,这是有道理的。

测试输入:

我正在使用:

  • Lucene 8.9.0版
  • StandardAnalyzer
  • 名为“body”的TextField
  • 经典查询解析器
  • 默认的查询解析器运算符(A B表示“A或B”)
  • 以下6个测试文件:

1.苹果
1.橘子
1.苹果桔子
1.香蕉
1.苹果香蕉
1.橘子香蕉
请参阅此处以获取正式的“经典查询解析器”语法文档。

第一个测试用例:x1个月10个月1个月

我的转述:“* 包含A但不能包含B的文档 *”
以下查询字符串...

apples -oranges
apples NOT oranges
apples OR -oranges
apples OR NOT oranges

...都使用org.apache.lucene.queryparser.classic.QueryParser解析为同一个查询。该查询为:

body:apples -body:oranges

因此,它们都产生相同的点击:

doc = 0; score = 0.3648143
field = apples

doc = 4; score = 0.2772589
field = apples bananas

第二个测试用例:-X

以下查询字符串...

-apples
 NOT apples
-anything
NOT anything

...都被解析为以下2个查询:

-body:apples
-body:anything

无论源文档中的数据如何,这些查询始终生成 * 无命中
这可能是违反直觉的--尤其是-anything
在第一种情况下,单个子句-body:apples强制所有包含apples的文档的得分为零。但是现在查询中没有更多的子句-因此,
没有额外的信息 * 可用于计算剩余文档的任何得分。因此,它们都停留在“未得分”的初始状态。因此,无法返回任何文档。
在第二种情况-body:anything中,总体逻辑是相同的。在从评分考虑中移除包含anything的所有文档之后(即使这意味着根本不移除文档),查询中仍然没有可用于评分目的的更多信息。

第三个测试用例:A AND -B

以下查询字符串...

apples AND -oranges
apples AND NOT oranges

...都被解析为同一个查询:

+body:apples -body:oranges

这与第一个测试用例非常相似--实际上返回了相同得分的相同命中。当研究-NOT之间的差异时,这个特定的用例并不重要,因为它给出了与测试用例1相同的结果。
题外话:一个更有趣的测试用例是A B+A B,其中结果和评分存在差异(+A强制要求A),但这超出了本问题的范围。

更多背景

查看另一个答案中提到的电子邮件线程,这里有一个most relevant section的副本,在此复制以供参考:

  • 开始复制节 *

总而言之...

  1. Lucene的QueryParser类不解析布尔表达式--看起来像,但实际上不是。
  2. Lucene的BooleanQuery子句不对布尔查询建模......它对聚合查询建模。
    1.将lucene“BooleanQuery”中可用的选项表示为字符串的最原生的方式是使用+/-前缀,其中...
    +foo...表示foo是必需子句,文档必须与之匹配
    -foo...表示foo是禁止的子句,文档不能与之匹配
    foo...意味着foo是可选子句,与之匹配的文档将因此获得分数。
    1.为了使那些有简单需求的人更容易,QueryParser“假装”它通过将A AND B解释为+A +B来解析布尔表达式;将A OR B转换为A B,将NOT A转换为-A
    1.如果您将QueryParser上的默认运算符更改为AND,那么事情会变得更加复杂,主要是因为QueryParser会将A B视为与+A +B相同
    1.你应该避免用ANDORNOT来思考......用OPTIONALREQUIREDPROHIBITED来思考......你的生活会轻松得多:文档会更有意义,电子邮件列表上的对话会更有协同效应,酒会更甜,食物会更美味。
  • 复制节结束 *
rseugnpd

rseugnpd3#

很久以前,我在什么地方读到过这个...和你的猜测差不多...:)
NOT运算符不能只与一个术语一起使用。例如,以下搜索将不返回任何结果:
NOT "jakarta apache"
而“-”或禁止运算符排除了包含“-”符号后的术语的文档...
希望这将是有用的..

相关问题