8

给定一个包含此文本的文档,索引在名为 Content 的字段中:

The dish ran away with the spoon.

以下查询无法匹配该文档:

+Content:dish +(-Content:xyz)   <-- no results!

我希望将查询视为必须包含“dish”,不得包含“xyz”。失败的是“不得已”的部分。

我知道 +- 组合看起来很有趣,但在语法上它应该是正确的,特别是考虑到以下变体都有效:

+Content:dish +(-Content:xyz +Content:spoon)   <-- this works
+Content:dish -Content:xyz                     <-- this works

那么为什么不起作用+(-Content:xyz)呢?这是设计使然,还是错误,或者我只是错过了什么?我正在使用 Lucene.Net,但我认为常规 Lucene 的行为相同。

4

1 回答 1

13

Lucene 并不是从一个完整的视图开始的,比如一个 SQL 数据库。Lucene 从没有匹配的文档开始,并根据搜索的子句查找内容。这就是为什么:

-Content:xyz

靠它自己真的行不通。它知道不带入 content:xyz,但没有得到任何匹配的文件。您的查询也是如此,因为它被放置在子查询中。

-Content:xyz首先评估,它自己没有文档。那么你有,有效地

+Content:dish +(no documents)

-将其视为一个AND NOT而不是简单的一个很有用NOT(尽管不要认为这意味着 +/- 和 AND/OR/NOT 语法必须直接相互映射)。

如果您希望能够执行这样一个孤独的否定查询,您需要首先引入所有文档。MatchAllDocsQuery是实现这一目标的最佳方式,例如:

BooleanQuery query = new BooleanQuery();
query.add(new BooleanClause(new MatchAllDocsQuery(), BooleanClause.Occur.SHOULD));
query.add(new BooleanClause(new TermQuery(new Term("Content","xyz")), BooleanClause.Occur.MUST_NOT));

将等效于仅对 WHERE 子句进行否定的 SQL 样式查询。

当然,在您列出的情况下,这并不是真正必要的,因为:

+Content:dish -Content:xyz

完全够用。

于 2013-04-18T19:00:40.103 回答