匹配文档,如果它在elasticsearch中包含多个嵌套文档

时间:2016-11-21 18:45:25

标签: elasticsearch

我有一个包含嵌套文档数组的文档。如果文档包含所有指定的嵌套文档,我需要返回匹配项。

这是映射的相关部分:

"element": {
  "dynamic": "false",
  "properties": {
    "tenantId": {
      "type": "string",
      "index": "not_analyzed"
    },
    "fqn": {
      "type": "string",
      "index": "not_analyzed"
    },
    "id": {
      "type": "string",
      "index": "not_analyzed"
    },
    "name": {
      "type": "string",
      "index": "not_analyzed"
    },
    "type": {
      "type": "string",
      "index": "not_analyzed"
    },
    "location": {
      "type": "string",
      "index": "not_analyzed"
    },
    "tags": {
      "type": "nested",
      "properties": {
        "id": {
          "type": "string",
          "index": "not_analyzed"
        },
        "dataSourceId": {
          "type": "long",
          "index": "not_analyzed"
        },
        "name": {
          "type": "string",
          "index": "not_analyzed"
        },
        "value": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}

目标是能够返回包含所有标签列表的元素(尽管该元素允许包含超出搜索要求的其他标签)。

这是我到目前为止所做的:

{
   "query": {
     "bool": {
       "filter": {
          "nested": {
             "path": "tags",
             "query": {
                "bool": {
                   "must": [
                      {
                        "bool": {
                          "must":{
                             "term": { "tags.name": "name1" },
                             "term": { "tags.value": "value1" }
                          }
                        }
                      },
                      {
                        "bool": {
                          "must":{
                             "term": { "tags.name": "name2" },
                             "term": { "tags.value": "value2" }
                          }
                        }
                      }
                   ]
                }
             }
          }
       }
    }
  }
}

这种方法的问题在于它返回带有多个标记值的0次点击(它适用于单个值)。我认为这是因为查询要求标签具有多个名称和值以便匹配,这显然不会发生。有谁知道如何查询包含所有标签列表的元素?

编辑:这是使用elasticsearch 5.0

1 个答案:

答案 0 :(得分:4)

我们想通了。答案是创建两个嵌套查询,而不是对同一个嵌套查询有两个子句。

{
 "query":{
   "bool":{
     "must":[{
        "nested":{
           "path":"tags",
           "query":{
              "bool":{
                 "must":[
                    {"term":{"tags.name":"name1"}},
                    {"term":{"tags.value":"value1"}}
                 ]
              }
           }
        }
     },
     {
        "nested":{
           "path":"tags",
           "query":{
              "bool":{
                 "must":[
                    {"term":{"tags.name":"name2"}},
                    {"term":{"tags.value":"value2"}}
                 ]
              }
           }
        }
     }]
   }
 }
}