Elasticsearch Copy_to数据需要复制自己的子文档

时间:2019-06-03 10:08:09

标签: elasticsearch elasticsearch-6

预先感谢您的帮助。

我创建的ES映射为:

{"mappings": {
            "policy": {
                "properties": {
                    "name": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "tags": {
                        "properties": {
                            "scope": {
                                "type": "text",
                                "store": "true",
                                "copy_to": [
                                    "tags.tag_scope"
                                ]
                            },
                            "tag": {
                                "type": "text",
                                "store": "true",
                                "copy_to": [
                                    "tags.tag_scope"
                                ]
                            },
                            "tag_scope": {
                                "type": "text",
                                "store": "true"
                            }
                        }
                    }
                }
            }
        }

    }

当我索引策略文档时,将来自不同标签文档的所有标签和作用域值复制到tag_scope属性。

例如,我添加了一个关于弹性搜索的文档:

{
                    "name": "policy1",
                    "tags": [
                        {
                            "tag": "pepsi",
                            "scope": "prod"
                        },
                        {
                            "tag": "coke",
                            "scope": "dev"
                        }
                    ]
                }

它将所有4个值存储在tag_scope文档中,如下所示:

“ tags.tag_scope”:[                         “百事可乐”,                         “测试”,                         “可乐”,                         “ dev”                     ]

我的例外是,它应该像这样存储:

 {
                        "name": "policy1",
                        "tags": [
                            {
                                "tag": "pepsi",
                                "scope": "prod",
                                 "tag_scope" : ["pepsi","prod"]
                            },
                            {
                                "tag": "coke",
                                "scope": "dev",
                                 "tag_scope" : ["coke","dev"]
                            }
                        ]
                    }

能否请您帮我做正确的映射?

1 个答案:

答案 0 :(得分:1)

您要寻找的是Nested Datatype。将映射更改为以下内容:

PUT <your_index_name>
{  
   "mappings":{  
      "policy":{ 
         "properties":{  
            "name":{  
               "type":"text",
               "fields":{  
                  "keyword":{  
                     "type":"keyword",
                     "ignore_above":256
                  }
               }
            },
            "tags":{  
               "type": "nested", 
               "properties":{  
                  "scope":{  
                     "type":"text",
                     "store":"true",
                     "copy_to":[  
                        "tags.tag_scope"
                     ]
                  },
                  "tag":{  
                     "type":"text",
                     "store":"true",
                     "copy_to":[  
                        "tags.tag_scope"
                     ]
                  },
                  "tag_scope":{  
                     "type":"text",
                     "store":"true",
                     "fields": {                <---- Added this
                       "keyword": {
                          "type": "keyword"
                       }
                     }
                  }
               }
            }
         }
      }
   }
}

注意如何将tags设置为nested类型。这样可以将以下内容存储为单独的文档本身,在您的情况下,tags基本上有两个嵌套的文档。

{  
   "tag":"coke",
   "scope":"dev"
}

现在您的tags.tag_scope应该就是您期望的样子。

现在,在查询所需内容时,下面是Nested Query的样子。

嵌套查询:

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "tags",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "tags.tag_scope": "pepsi"
                    }
                  },
                  {
                    "match": {
                      "tags.tag_scope": "prod"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

要返回唯一的tags.tag_scope值列表,您需要返回聚合查询。请注意,我已经提到size:0,这意味着我只想查看聚合结果,而不是正常的查询结果。

汇总查询:

POST <your_index_name>/_search
{  
   "size":0,
   "query":{  
      "bool":{  
         "must":[  
            {  
               "nested":{  
                  "path":"tags",
                  "query":{  
                     "bool":{  
                        "must":[  
                           {  
                              "match":{  
                                 "tags.tag_scope":"pepsi"
                              }
                           },
                           {  
                              "match":{  
                                 "tags.tag_scope":"prod"
                              }
                           }
                        ]
                     }
                  }
               }
            }
         ]
      }
   },
   "aggs":{                        <----- Aggregation Query Starts Here
      "myscope":{  
         "nested":{  
            "path":"tags"
         },
         "aggs":{  
            "uniqui_scope":{  
               "terms":{  
                  "field":"tags.tag_scope.keyword",
                  "size":10
               }
            }
         }
      }
   }
}

聚集响应:

{
  "took": 53,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "myscope": {
      "doc_count": 2,
      "uniqui_scope": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "coke",
            "doc_count": 1
          },
          {
            "key": "dev",
            "doc_count": 1
          },
          {
            "key": "pepsi",
            "doc_count": 1
          },
          {
            "key": "prod",
            "doc_count": 1
          }
        ]
      }
    }
  }
}

希望这会有所帮助。