Elasticsearch Copy_to данные должны быть скопированы в собственный поддокумент - PullRequest
0 голосов
/ 03 июня 2019

Заранее спасибо за помощь.

Я создал отображение 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 Ответ

1 голос
/ 03 июня 2019

То, что вы ищете, это 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
          }
        ]
      }
    }
  }
}

Надеюсь, это поможет.

...