Elasticsearch 数组属性必须包含给定的数组项

Eke*_*ein 5 arrays term elasticsearch

我有如下文件:

{
    "tags" => [
        "tag1",
        "tag2",
    ],
    "name" => "Example 1"
}

{
    "tags" => [
        "tag1",
        "tag3",
        "tag4"
    ],
    "name" => "Example 2"
}
Run Code Online (Sandbox Code Playgroud)

我现在想要的是进行术语搜索,其中给定的数组可能如下所示:

[tag1, tag3]
Run Code Online (Sandbox Code Playgroud)

预期命中应该是:

{
    "tags" => [
        "tag1",
        "tag3",
        "tag4"
    ],
    "name" => "Example 2"
}
Run Code Online (Sandbox Code Playgroud)

但是,当我执行以下查询时:

GET _search
{
    "query": {
        "filtered": {
           "query": {
               "match_all": {}
           },
           "filter": {
               "bool": {
                   "must": [
                      {
                          "terms": {
                             "tags": [
                                "tag1",
                                "tag3"
                             ]
                          }
                      }
                   ]
               }
           }
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

因为示例 1 和示例 2 都包含 tag1 或 tag3,所以我得到了“示例 1”和“示例 2”作为命中。通过查看条款的文档,我发现条款实际上是一个包含查询。

在这种情况下,我如何确保示例 2 是使用 tag1 和 tag3 进行查询时的唯一命中?

Abd*_*jid 6

对于那些在 2020 年关注这一点的人来说,您可能已经注意到它minimum_should_match很久以前就已被弃用。

目前有一个替代方案,那就是使用terms_set.

例如:

{
  "query": {
    "terms_set": {
      "programming_languages": {
        "terms": [ "c++", "java", "php" ],
        "minimum_should_match_field": "required_matches"
      }
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

上面的示例假设required_matches存在一个包含整数的字段,该整数定义了应该有多少个匹配项。

更有用的是替代字段minimum_should_match_script

请参阅下面的示例:

{
  "query": {
    "terms_set": {
      "programming_languages": {
        "terms": [ "c++", "java", "php" ],
        "minimum_should_match_script": {
          "source": "2"
        },
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您始终可以使用上下文内部filter来使其成为过滤器。

在这里阅读更多内容


Rus*_*Cam 4

您需要通过添加到过滤器来将执行模式设置为“and”,以便所有术语都必须包含在文档中才能被视为匹配"execution": "and"terms

GET _search
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
            "terms": {
               "tags": [
                  "tag1",
                  "tag3"
               ],
               "execution": "and"
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

这实际上与使用所有项的结合构建过滤器相同bool must,但形式更紧凑。