Elasticsearch - Применение многоуровневого фильтра для вложенного сегмента агрегации? - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь получить отдельные вложенные объекты, применяя несколько фильтров.

В основном в Elasticsearch у меня есть города в качестве документа верхнего уровня, а внутри у меня есть вложенные документы граждан, в которых есть документы других вложенных домашних животных.

Я пытаюсь привлечь всех граждан, для которых на всех этих трех уровнях применяются определенные условия (города, граждане и домашние животные):

Give me all distinct citizens 
that have age:"40", 
that have pets "name":"Casper",
from cities with office_type="secondary" 

Я знаю, что для фильтрации 1-го уровня я могу использоватьусловие запроса, а затем, если мне нужно отфильтровать вложенных граждан, я могу добавить фильтр на уровне агрегации.

Я использую эту статью в качестве примера: https://iridakos.com/tutorials/2018/10/22/elasticsearch-bucket-aggregations.html

Запрос работает такдалеко:

GET city_offices/_search
{
  "size" : 10,
   "query": {
    "term" : { "office_type" : "secondary" } 
  },
  "aggs": {
      "citizens": {
        "nested": {
          "path": "citizens"
        },
        "aggs": {
          "inner_agg": {
            "filter": {
                "term": { "citizens.age": "40" }  
              } ,
              "aggs": {
                  "occupations": {
                    "terms": {
                      "field": "citizens.occupation"
                    }
                  }
              }
          }
        }
      }
    }
}

НО: как добавить условие вложенного фильтра «домашние животные»?

Отображение:

PUT city_offices
{
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "doc": {
      "properties": {
        "city": {
          "type": "keyword"
        },
        "office_type": {
          "type": "keyword"
        },
        "citizens": {
          "type": "nested",
          "properties": {
            "occupation": {
              "type": "keyword"
            },
            "age": {
              "type": "integer"
            },
            "pets": {
              "type": "nested",
              "properties": {
                "kind": {
                  "type": "keyword"
                  },
                "name": {
                  "type": "keyword"
                },
                "age": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    }
  }
}

Индексные данные:

PUT /city_offices/doc/1
{
   "city":"Athens",
   "office_type":"secondary",
   "citizens":[      
      {
         "occupation":"Statistician",
         "age":30,
         "pets":[
            {
               "kind":"Cat",
               "name":"Phoebe",
               "age":14
            }
         ]
      },
      {
         "occupation":"Librarian",
         "age":30,
         "pets":[
            {
               "kind":"Rabbit",
               "name":"Nino",
               "age":13
            }
         ]
      },   
      {
         "occupation":"Librarian",
         "age":40,
         "pets":[
            {
               "kind":"Rabbit",
               "name":"Nino",
               "age":13
            }
         ]
      },      
      {
         "occupation":"Statistician",
         "age":40,
         "pets":[
            {
               "kind":"Rabbit",
               "name":"Casper",
               "age":2
            },
            {
               "kind":"Rabbit",
               "name":"Nino",
               "age":13
            },
            {
               "kind":"Dog",
               "name":"Nino",
               "age":15
            }
         ]
      }   
   ]
}

1 Ответ

0 голосов
/ 19 февраля 2019

Так что я нашел решение для этого.В основном я применяю фильтры верхнего уровня в разделе запросов, а затем применяю остальные условия в агрегатах.

Сначала я применяю агрегацию фильтра уровня граждан, затем я захожу внутрь вложенных домашних животных и применяю фильтр, а затем мне нужно получитьвернуться к уровню граждан (используя reverse_nested: граждане), а затем установить термин, который будет генерировать окончательный сегмент.

Запрос выглядит следующим образом:

GET city_offices/_search
{
  "size" : 10,
   "query": {
    "term" : { "office_type" : "secondary" } 
  },
  "aggs": {
      "citizens": {
        "nested": {
          "path": "citizens"
        },
        "aggs": {
          "inner": {
            "filter": {
                "term": { "citizens.age": "40" }  
              } ,
              "aggs": {
                  "occupations": {
                    "nested": {
                      "path": "citizens.pets"
                    },
                    "aggs": {
                      "inner_pets": {
                        "filter": {
                            "term": { "citizens.pets.name": "Casper" }  
                          } ,
                           "aggs": {
                             "lll": {
                               "reverse_nested": {
                                  "path": "citizens"
                                },
                                "aggs": {
                                   "xxx": {
                                      "terms": {
                                        "field": "citizens.occupation",
                                        "size": 10
                                      }
                                  }
                                }
                              }
                           }
                      }
                    }
                  }
              }
          }
        }
      }
    }
}

Область ответа выглядит следующим образом:

              "xxx": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                  {
                    "key": "Librarian",
                    "doc_count": 1
                  },
                  {
                    "key": "Statistician",
                    "doc_count": 1
                  }
                ]
              }

Любые другие предложения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...