Группировка Elasticsearch по полю и получение количества корзин, содержащих более двух документов.

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

Удалось получить ведра и сохранить размер достаточно большим, чтобы получить все ведра, но я действительно хочу знать, как получить общее количество ведер:

"aggregations": {
    "by_universalId": {
        "terms": {
          "size": 10, 
            "field": "universalId",
            "min_doc_count": 2,
            "order": [
                {
                    "_count": "desc"
                },
                {
                    "_key": "asc"
                }
            ]
        }
    }
}

В этой ветке GitHub говорится, что селектор корзины — это правильный способ получить подсчет, но не мог найти способ сделать это. Любая помощь приветствуется, спасибо.

EDIT1: Вот как выглядят данные индекса:

{"id":"1", "universalId": "a"}
{"id":"2", "universalId": "a"}
{"id":"3", "universalId": "b"}
{"id":"4", "universalId": "b"}
{"id":"5", "universalId": "c"}
{"id":"6", "universalId": "c"}
{"id":"7", "universalId": "d"}
{"id":"8", "universalId": "d"}
{"id":"9", "universalId": "e"}
{"id":"10", "universalId": "e"}
{"id":"11", "universalId": "f"}
{"id":"12", "universalId": "f"}
{"id":"13", "universalId": "f"}
{"id":"14", "universalId": "g"}
{"id":"15", "universalId": "g"}
{"id":"16", "universalId": "g"}
{"id":"17", "universalId": "g"}
{"id":"18", "universalId": "h"}
{"id":"19", "universalId": "i"}
{"id":"20", "universalId": "j"}

И когда я запускаю этот запрос, я получаю счет как 5 вместо 7:

{
  "aggregations": {
      "by_universalId": {
        "terms": {
          "size": 5,
          "field": "universalId",
          "min_doc_count": 2,
          "order": [
            {
              "_count": "desc"
            },
            {
              "_key": "asc"
            }
          ]
        }
      },
      "bucketcount": {
        "stats_bucket": {
          "buckets_path": "by_universalId._count"
        }
      }
    }
}

Вот что я получаю:

"aggregations" : {
    "by_universalId" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 4,
      "buckets" : [
        {
          "key" : "g",
          "doc_count" : 4
        },
        {
          "key" : "f",
          "doc_count" : 3
        },
        {
          "key" : "a",
          "doc_count" : 2
        },
        {
          "key" : "b",
          "doc_count" : 2
        },
        {
          "key" : "c",
          "doc_count" : 2
        }
      ]
    },
    "bucketcount" : {
      "count" : 5,
      "min" : 2.0,
      "max" : 4.0,
      "avg" : 2.6,
      "sum" : 13.0
    }
  }

Если я изменю размер на 10, я получу правильный счет, который равен 7.

Я ожидаю, что количество будет равно 7, независимо от размера, который я передаю с точки зрения агрегирования.

Детали версии Elasticsearch:

"version" : {
    "number" : "7.9.2",
    "build_flavor" : "default",
    "build_type" : "deb",

person Madhu    schedule 04.05.2021    source источник
comment
не могли бы вы объяснить свой вариант использования с помощью примера. Было бы здорово, если бы вы могли поделиться некоторыми примерами данных индекса и ожидаемыми результатами поиска.   -  person ESCoder    schedule 04.05.2021
comment
Я пытался найти дубликаты для сущности. Два документа будут считаться дубликатами, если они имеют одинаковый универсальный идентификатор. Теперь мне нужно подсчитать количество сущностей, у которых есть хотя бы один дубликат. Подобно тому, что Google показывает для дубликатов контактов в телефонах Android. Я попытаюсь создать образец данных индекса и ожидаемых результатов и обновлю сообщение.   -  person Madhu    schedule 04.05.2021


Ответы (1)


Если вы хотите получить общее количество сегментов, сформированных путем агрегации терминов (с минимальным числом документов, равным 2), вам необходимо использовать агрегация сегментов статистики

{
  "size": 0,
  "aggregations": {
    "by_universalId": {
      "terms": {
        "size": 10,
        "field": "universalId",
        "min_doc_count": 2,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      }
    },
    "bucketcount": {
      "stats_bucket": {
        "buckets_path": "by_universalId._count"
      }
    }
  }
}

Обновление 1:

Вы получаете количество сегментов с помощью агрегации stats_bucket (используя приведенный выше поисковый запрос). По умолчанию параметр size в агрегации условий по умолчанию равен 10.

size используется для установки количества сегментов, которые должны быть возвращены в результате агрегирования. Если вы укажете "size :5", то будут возвращены только 5 сегментов, и на основе этой статистики агрегация сегментов вернет число 5.

В вашем случае, если вы даже не передадите параметр size в агрегации терминов, вы получите счет как 7

person ESCoder    schedule 04.05.2021
comment
Зависит ли stats_bucket от size в терминах aggregation(by_universalId)? Поскольку bucketcount совпадает с size, если указано size, в противном случае он вернется к размеру страницы по умолчанию (в моем случае это было 10). - person Madhu; 04.05.2021
comment
@Madhu stats_bucket подсчитает количество сегментов, образованных агрегацией терминов. - person ESCoder; 05.05.2021
comment
@Madhu теперь вы получаете количество сегментов терминов, используя агрегацию сегментов статистики. Я обновил ответ относительно проблемы, связанной с параметром size. Пожалуйста, просмотрите обновленный ответ и дайте мне знать, решит ли это вашу проблему? - person ESCoder; 05.05.2021
comment
да, в этом случае не передача size работает, но если количество сегментов велико (скажем, 10 000), то просто для подсчета сегментов я буду получать все сегменты. Есть ли какой-либо другой способ сделать это, не извлекая все сегменты или ограничивая количество сегментов, которые я извлекаю в любое время, до небольшого числа, но при этом получая общее количество сегментов, соответствующее критериям? - person Madhu; 05.05.2021
comment
@Madhu Насколько я знаю, нет другого способа найти дубликаты (с минимальным количеством документов 2), кроме использования агрегации ведра (здесь термин агрегация). И для этого вам нужно получить все корзины и соответствующим образом установить параметр size, если у вас есть 10 000 документов. - person ESCoder; 05.05.2021