Elasticsearch - агрегирование по нескольким полям, фильтрация по счету и упорядочение по счету - PullRequest
1 голос
/ 13 марта 2019

Я немного новичок в агрегации и хочу создать эквивалент следующего SQL:

select fullname, natcode, count(1) from table where birthdate = '18-sep-1993' group by fullname, natcode having count(1) > 2 order by count(1) desc

Итак, если у меня есть следующие данные:
enter image description here

Мне нужно получить результаты как:
enter image description here

Как видите, результаты сгруппированы по полному имени и natcode, имеютcount> 2 и упорядочены по count

Мне удалось сформировать следующий запрос:

{
  "size": 0,
  "aggs": {
    "profs": {
      "filter": {
        "term": {
          "birthDate": "18-Sep-1993"
        }
      },
      "aggs": {
        "name_count": {
          "terms": {
            "field": "fullName.raw"
          },
          "aggs": {
            "nat_count": {
              "terms": {
                "field": "natCode"
              },
              "aggs": {
                "my_filter": {
                  "bucket_selector": {
                    "buckets_path": {
                      "the_doc_count": "_count"
                    },
                    "script": {
                      "source": "params.the_doc_count>2"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Что достигнуто: Фильтрация по дате, созданиекорзина с полным именем (name_count) и вложенная корзина с natcode (nat_count) и фильтрующая корзина natcode с количеством документов.

Проблема с этим: Я также вижу пустые корзины name_count.Я хочу только ведра, которые имеют необходимое количество.Ниже приведен пример результатов

"aggregations": {
    "profs": {
      "doc_count": 3754,
      "name_count": {
        "doc_count_error_upper_bound": 4,
        "sum_other_doc_count": 3732,
        "buckets": [
          {
            "key": "JOHN SMITH",
            "doc_count": 3,
            "nat_count": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "111",
                  "doc_count": 3
                }
              ]
            }
          },
          {
            "key": "MIKE CAIN",
            "doc_count": 3,
            "nat_count": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "205",
                  "doc_count": 3
                }
              ]
            }
          },
          {
            "key": "JULIA ROBERTS",
            "doc_count": 2,
            "nat_count": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": []
            }
          },
          {
            "key": "JAMES STEPHEN COOK",
            "doc_count": 2,
            "nat_count": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": []
            }
          }

В результатах я не хочу, чтобы последние два имени (Джулия Робертс и Джеймс Стивен Кук) показывались

Кроме того, чтоотсутствует: Порядок на счетчике группы в конце.Я хотел бы, чтобы группа (полное имя, natcode) с наибольшим количеством отображалась

Требуется дальше: Группирование должно быть выполнено еще на нескольких полях, чтобы онибыло бы похоже на 4 поля.

Пожалуйста, извините, если бы я мог использовать какие-то неправильные термины.Надеюсь, вы получите представление о том, какая помощь требуется.Спасибо

1 Ответ

1 голос
/ 13 марта 2019

Ниже показан ваш запрос.

Обязательный запрос (окончательный ответ)

POST <your_index_name>/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": {
        "term": {
          "birthDate": "18-sep-1993"
        }
      }
    }
  }, 
  "aggs": {
    "groupby_fullname": {
      "terms": {
        "field": "fullName.raw",
        "size": 2000
      },
      "aggs": {
        "natcode_filter": {
          "bucket_selector": {
            "buckets_path": {
              "hits": "groupby_natcode._bucket_count"
            },
            "script": "params.hits > 0"
          }
        },
        "groupby_natcode": {
          "terms": {
            "field": "natCode",
            "size": 2000,
            "min_doc_count": 2
          }
        }
      }
    }
  }
}

Альтернативное решение: (аналогично выбору отличного)

В крайнем случае, что я могу прийтинужно сделать что-то вроде select Different на основе fullName + "_" + natCode.Так что в основном ваши ключи будут иметь форму JOHN SMITH_111.Это дает вам точный результат, за исключением того, что ключи будут в этой форме.

POST <your_index_name>/_search
{  
   "size":0,
   "query":{  
      "bool":{  
         "filter":{  
            "term":{  
               "birthDate":"18-sep-1993"
            }
         }
      }
   },
   "aggs":{  
      "name_count":{  
         "terms":{  
            "script":{  
               "inline":"doc['fullName.raw'].value + params.param + doc['natCode'].value",
               "lang":"painless",
               "params":{  
                  "param":"_"
               }
            }
         },
         "aggs":{  
            "my_filter":{  
               "bucket_selector":{  
                  "buckets_path":{  
                     "doc_count":"_count"
                  },
                  "script":"params.doc_count > 2"
               }
            }
         }
      }
   }
}

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

...