给定两个文档,每个文档有两个字段:
1. title: United Kingdom requested meeting of United Nations
content: The United Nations will hear statements from the United Kingdom (...)
2. title: Airlines face scrutiny across nation
content: United States airline United Airlines has faced increasing (...)
我正在寻找一个 Lucene 查询,它将 A) 在标题或内容字段中匹配“united”一词的实例,但在后跟“States”或“Kingdom”时不匹配 B) 重要的是,匹配两个文档,即使它们同时包含想要的和不需要的短语。
我的第一个停靠点是
spanNot()
,它意味着在包含、排除顺序中接受两个 spanTerm
查询,后跟一个 dist
整数和一个布尔值,指示这些术语是否应该按顺序排列。例如:
spanNot(title:united, title:states, 1, true)
鉴于此,我使用
BooleanQuery
链接了必要的查询,以便查询是这样的:
(+spanNot(title:united, title:states, 1, true) +spanNot(title:united, title:kingdom, 1, true))
(+spanNot(content:united, content:states, 1, true) +spanNot(content:united, content:kingdom, 1, true))
如您所见,上面有两组查询,逻辑上应该这样读:“(标题必须包含联合但不是美国,并且标题必须包含联合但不是英国)或(内容必须包含联合但不是美国,并且内容必须包含美国但不是英国)“
从概念上讲,这对我来说非常有意义,但是,我发现我的查询结果——无论是初始的
spanNot
还是更长的链式 BooleanQuery
版本——都是不正确的。要么整个文件不匹配,要么每次提到“联合”这个词都匹配——很难找出原因。
有关其他详细信息: 我在 Clojure 中使用 lucene java 库实现查询构建器,但使用 Kibana 的 Lucene 查询功能测试查询,测试绝对应该匹配的文档。 使用 Lucene v 7.7 - 可能会进行升级,但我认为这不会解决我的问题。
任何见解将不胜感激。
我认为,您应该使用 Boolean + Phrase 查询。 我不知道库中的 Lucene 语法(我认为你需要 PhraseQuery),但对于常规请求,你可以使用以下查询:
{
"query": {
"bool": {
"should": [
{
"bool": {
"filter": [
{
"match": {
"title": "united"
}
}
],
"must_not": [
{
"match_phrase": {
"title": "United Kingdom"
}
},
{
"match_phrase": {
"title": "United States"
}
}
]
}
},
{
"bool": {
"filter": [
{
"match": {
"content": "united"
}
}
],
"must_not": [
{
"match_phrase": {
"content": "United Kingdom"
}
},
{
"match_phrase": {
"content": "United States"
}
}
]
}
}
]
}
}
}
经过大量 Lucene 文档和源代码调试后,此问题已得到修复。以下是在 Lucene 中编写此查询的正确方法:
spanNot(title:united, spanOr([spanNear([title:united, title:states], 0, true), spanNear([title:united, title:kingdom], 0, true)]), 0, 0) spanNot(content:united, spanOr([spanNear([content:united, content:states], 0, true), spanNear([content:united, content:kingdom], 0, true)]), 0, 0) spanNot(summary:united, spanOr([spanNear([summary:united, summary:states], 0, true), spanNear([summary:united, summary:kingdom], 0, true)]), 0, 0)
如果难以阅读,它是 3 个单独的查询(每个字段一个),由带有术语查询的
spanNot
和一个 spanOr
排除组成,它本身由两个 spanNear
查询组成 - 一个对于每个排除项。
之前的问题是对于SHOULD和MUST的任何分配,排除项和字段的组合太多。执行此搜索的正确方法是对每个字段进行一次彻底查询。