Lucene查询失败,必须混合/必须_否

问题描述 投票:6回答:1

给出带有此文本的文档,在名为Content的字段中建立索引:

The dish ran away with the spoon.

以下查询未能匹配该文档:

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

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

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

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

所以+(-Content:xyz)为什么不起作用?这是设计使然,还是错误,还是我只是想念一些东西?我正在使用Lucene.Net,但我认为常规的Lucene的行为相同。

lucene lucene.net
1个回答
10
投票

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));

将等效于SQL样式查询,只对WHERE子句取反。

当然,自从您列出以来,这实际上不是必需的:

+Content:dish -Content:xyz

完全足够。

© www.soinside.com 2019 - 2024. All rights reserved.