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

时间:2015-08-10 09:54:21

标签: arrays elasticsearch term

我的文档看起来像:

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

{
    "tags" => [
        "tag1",
        "tag3",
        "tag4"
    ],
    "name" => "Example 2"
}

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

[tag1, tag3]

预期命中应该是:

{
    "tags" => [
        "tag1",
        "tag3",
        "tag4"
    ],
    "name" => "Example 2"
}

但是,当我进行如下查询时:

GET _search
{
    "query": {
        "filtered": {
           "query": {
               "match_all": {}
           },
           "filter": {
               "bool": {
                   "must": [
                      {
                          "terms": {
                             "tags": [
                                "tag1",
                                "tag3"
                             ]
                          }
                      }
                   ]
               }
           }
       }
    }
}

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

在这种情况下,我怎样才能确保在使用tag1和tag3查询时,示例2是唯一的命中?

3 个答案:

答案 0 :(得分:2)

您需要将{strong> execution mode 设置为“和”,方法是将"execution": "and"添加到terms过滤器,以便所有条款必须包含在文档中才能被视为匹配

GET _search
{
   "query": {
      "filtered": {
         "query": {
            "match_all": {}
         },
         "filter": {
            "terms": {
               "tags": [
                  "tag1",
                  "tag3"
               ],
               "execution": "and"
            }
         }
      }
   }
}

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

答案 1 :(得分:1)

对于那些在2020年正在研究此问题的人,您可能已经注意到minimum_should_match早已过时。

当前有一种替代方法,可以使用terms_set

例如:

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

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

更有用的是替代字段minimum_should_match_script

请参见以下示例:

{
  "query": {
    "terms_set": {
      "programming_languages": {
        "terms": [ "c++", "java", "php" ],
        "minimum_should_match_script": {
          "source": "2"
        },
      }
    }
  }
}

您总是可以在filter上下文内部使用它来使其成为过滤器。

了解更多here

答案 2 :(得分:0)

您可以设置minimum_should_match以匹配您的数组:

{
    "query": {
        "filtered": {
           "query": {
               "match_all": {}
           },
           "filter": {
               "bool": {
                   "must": [
                      {
                          "terms": {
                             "tags": ["tag1","tag3"],
                             "minimum_should_match": 2
                          }
                      }
                   ]
               }
           }
       }
    }
}