【问题标题】:what is the difference between - and NOT operator in Lucene?Lucene 中的 - 和 NOT 运算符有什么区别?
【发布时间】:2011-04-19 19:14:02
【问题描述】:

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 则不然。是这样吗?

【问题讨论】:

    标签: java lucene operators


    【解决方案1】:

    快速回答:

    -(禁止)运算符和NOT 运算符的行为没有区别。我认为,文档并没有特别清楚地说明这一点。

    NOT- 的同义词,此处。

    这可以通过一些测试来证明,总结如下。

    另请参阅此答案末尾的摘录以获取摘要,该摘要很好地提炼了有关 Lucene 经典查询解析器的各个要点。

    可能最重要的一点是ANDORNOT 运算符与“传统”布尔运算符不同。它们有细微的不同。这是因为 Lucene 的经典查询解析器仅部分依赖于布尔运算——特别是文档是否应该接收分数。除此之外,运算符可以以明显的“非布尔”方式使用,以影响文档相对于彼此的评分方式。

    这是有道理的,因为 Lucene 的目的是按相关性顺序显示结果


    测试输入:

    我正在使用:

    • Lucene 8.9.0
    • StandardAnalyzer
    • 一个名为“body”的TextField
    • 经典查询解析器
    • 默认查询解析器运算符(A B 表示“A 或 B”)
    • 以下6个测试文档:
    1. 苹果
    2. 橙子
    3. 苹果橙子
    4. 香蕉
    5. 苹果香蕉
    6. 橙子香蕉

    有关官方“经典查询解析器”语法文档,请参阅here


    第一个测试用例:A -B

    我的解释:“包含 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 子句不模拟布尔查询......它 模型聚合查询。

    3. 表示 lucene 中可用选项的最原生方式 “BooleanQuery”作为字符串带有 +/- 前缀,其中...

    +foo ... 表示 foo 是必需的子句,文档必须匹配它

    -foo ... 表示 foo 是禁止的子句,文档不能匹配它

    foo ... 表示 foo 是一个可选子句,匹配它的文档将 这样做可以获得分数收益。

    1. 试图让那些拥有 简单的需求,QueryParser "fakes" 它解析布尔表达式 通过将A AND B 解释为+A +BA OR B 作为 A BNOT A 作为 -A

    2. 如果您将QueryParser 上的默认运算符更改为AND,那么 事情变得更复杂了,主要是因为那时QueryParser 对待 A B+A +B

    3. 你应该避免用ANDORNOT 来思考...... OPTIONALREQUIREDPROHIBITED 的条款...你的生活会很丰富 更容易:文档将更有意义,电子邮件上的对话 清单会更协同,酒会更甜,食物会 味道更好。

    结束复制部分

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 为了防止链接过时(或任何 SO 术语),您应该将回答问题的重要部分从链接复制到您的答案中。
      【解决方案3】:

      很久以前我在某个地方读到过这篇文章...与您的猜测相似...:)

      NOT 运算符不能只与一个术语一起使用。例如,以下搜索将不返回任何结果:

      NOT "jakarta apache"

      而“-”或禁止运算符排除包含“-”符号后的术语的文档...

      希望这会有用..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-10
        • 2023-03-15
        • 1970-01-01
        • 2018-08-16
        • 2012-10-10
        • 2010-12-25
        相关资源
        最近更新 更多