ElasticSearch — как получить агрегацию агрегации

Я очень новичок в эластичном поиске Я работаю на сайте знакомств, который имеет следующие данные: Одинарная - с полями: имя, signUpDate, состояние и другие поля данных.

Встреча - с полями: состояние, дата встречи, singlesInvolved и другие поля данных.

Это мои 2 индекса

Теперь мне нужно написать запрос, который возвращает следующее:

Для каждого штата, сколько одиноких людей, сколько встреч, максимальное время, в течение которого один человек был частью нашего веб-сайта, и среднее время, в течение которого один человек был частью нашего веб-сайта.

А также вернуть один результат, который является одним и тем же средним значением для всех состояний. Как этот пример:

[
 { //this one is the average of all states
    "singles": 45,
    "dates": 18,
    "minWaitingTime": 1644677979530,
    "avgWaitingTime": 15603
  },
  { //these are the averages of each state
    "state": "MA",
    "singles": 50,
    "dates": 23,
    "minWaitingTime": 1644677979530,
    "avgWaitingTime": 15603
  },
  {
    "state": "NY",
    "singles": 39,
    "dates": 13,
    "minWaitingTime": 1644850558872,
    "avgWaitingTime": 6033
  }
]

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

пока что у меня есть это:

GET /single,encounter/_search 
{
  "size": 0, 
  "aggs": {
    "bystate": {
      "terms": {
        "field": "state",
        "size": 59
      },
      "aggs": {
        "group-by-index": {
          "terms": {
            "field": "_index"
          }
        },
        "min_date": {
          "min": {
            "field": "signedUpAt"
          }
        },
        "avg_date": {
          "avg": {
            "field": "signedUpAt"
          }
        }
      }
    }
  }
}

Я не знаю, есть ли лучший способ сделать это, также я не знаю, как рассчитать среднее значение (одиночные встречи, встречи, среднее значение min_date и medium_date) для всех состояний, используя этот результат. Каждый результат предыдущего запроса выглядит так:

{
      "key" : "MA",
      "doc_count" : 164,
      "avg_date" : {
        "value" : 1.6457900076508965E12,
        "value_as_string" : "2022-02-25T11:53:27.650"
      },
      "min_date" : {
        "value" : 1.64467797953E12,
        "value_as_string" : "2022-02-12T14:59:39.530"
      },
      "group-by-index" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
          {
            "key" : "single",
            "doc_count" : 135
          },
          {
            "key" : "encounter",
            "doc_count" : 29
          }
        ]
      }
    },

Я был бы очень признателен за помощь в этом

Дополнение: сопоставление индексов. Сталкиваться:

{
  "encounter" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "avgAge" : {
          "type" : "integer",
          "index" : false,
          "doc_values" : false
        },
        "application" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "createdAt" : {
          "type" : "date",
          "format" : "date_hour_minute_second_millis"
        },
        "encounterId" : {
          "type" : "keyword"
        },
        "locationType" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "singleOneId" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "singleTwoId" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "serviceLine" : {
          "type" : "keyword"
        },
        "state" : {
          "type" : "keyword"
        },
        "rating" : {
          "type" : "keyword"
        }
      }
    },
    "settings" : {
      "index" : {
        "refresh_interval" : "1s",
        "number_of_shards" : "1",
        "provided_name" : "encounter",
        "creation_date" : "1643704661932",
        "number_of_replicas" : "1",
        "uuid" : "MliXQL_bRBKDN7_d8G_BYw",
        "version" : {
          "created" : "7100299"
        }
      }
    }
  }
}

И сингл:

{
  "single" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "id" : {
          "type" : "keyword"
        },
        "singleId" : {
          "type" : "keyword"
        },
        "state" : {
          "type" : "keyword"
        },
        "preferedGender" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "refresh_interval" : "1s",
        "number_of_shards" : "1",
        "provided_name" : "single",
        "creation_date" : "1643704662136",
        "number_of_replicas" : "1",
        "uuid" : "Js_tqZfRRx-IxbjVRRN4wQ",
        "version" : {
          "created" : "7100299"
        }
      }
    }
  }
}

Можно ли поделиться отображением индекса?

Miguel Barrios 22.03.2022 21:04

ПОЛУЧИТЬ /single или ПОЛУЧИТЬ /encounter, без _search

Miguel Barrios 22.03.2022 22:53

добавлено, как вы просили

chimera_girl 23.03.2022 10:46
0
3
43
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Ниже приведен пример запроса:

{
  "size": 0,
  "aggs": {
    "bystate": {
      "terms": {
        "field": "state",
        "size": 59
      },
      "aggs": {
        "group-by-index": {
          "terms": {
            "field": "_index"
          }
        },
        "min_date": {
          "min": {
            "field": "signedUpAt"
          }
        },
        "avg_date": {
          "avg": {
            "field": "signedUpAt"
          }
        }
      }
    },
    "avg_all_state": {
      "avg_bucket": {
        "buckets_path": "bystate>avg_date"
      }
    }
  }
}

это работает, как я могу получить среднее количество синглов и свиданий для всех штатов?

chimera_girl 23.03.2022 10:55

то же самое вы можете сделать и для синглов, сначала примените term aggregation к синглам, а затем используйте avg bucket aggregation

Sagar Patel 23.03.2022 11:04

спасибо, есть ли способ преобразовать средние значения в целое число (не с плавающей запятой или с двойной точностью) - без десятичной точки?

chimera_girl 23.03.2022 13:15

Да, проверьте документация. вы можете указать значение format, и на основе значения оно будет отформатировано.

Sagar Patel 23.03.2022 13:18

как я могу отфильтровать ответ по штату и/или полу (например, мужчины в Нью-Йорке, или только мужчины во всех штатах, или только статистика Нью-Йорка)?

chimera_girl 24.03.2022 07:22

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

Sagar Patel 24.03.2022 07:53

Другие вопросы по теме