SpanNot Lucene 查询过于严格或过于宽松

问题描述 投票:0回答:2

给定两个文档,每个文档有两个字段:

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 - 可能会进行升级,但我认为这不会解决我的问题。

任何见解将不胜感激。

elasticsearch text clojure lucene kibana
2个回答
0
投票

我认为,您应该使用 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"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

0
投票

经过大量 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的任何分配,排除项和字段的组合太多。执行此搜索的正确方法是对每个字段进行一次彻底查询。

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