Сортировка агрегатов по элементу субагрегата с несколькими сегментами

В Elasticsearch 2.0.0 я пытаюсь отсортировать корзины в агрегации с несколькими корзинами terms по количеству попаданий для заданного термина.

Вот пример, чтобы было понятнее. Скажем, у нас есть следующий набор данных, представляющий покупки клиентов:

[{
  "id": "95aee6b0-9c41-11e5-8994-feff819cdc9f",
  "name": "Ingrid Bergman",
  "channel": "WEB",
  "productId": 3124,
  "totalPreTax": 221.5
},
{
  "id": "95aee6b0-9c41-11e5-8994-feff819cdc9f",
  "name": "Ingrid Bergman",
  "channel": "MOB",
  "productId": 5527,
  "totalPreTax": 12.5
},
{
  "id": "95aee6b0-9c41-11e5-8994-feff819cdc9f",
  "name": "Ingrid Bergman",
  "channel": "WEB",
  "productId": 1188,
  "totalPreTax": 55.6
},
{
  "id": "2854b9d6-9c42-11e5-8994-feff819cdc9f",
  "name": "Luis Borges",
  "channel": "IPAD",
  "productId": 779,
  "totalPreTax": 119.0
}]

Что мне нужно, так это получить для каждого клиента среднее totalPreTax и их наиболее частое channel, отсортировав в алфавитном порядке по последнему (убывающую). То есть,

[{ 
   "id": "95aee6b0-9c41-11e5-8994-feff819cdc9f",
   "name": "Ingrid Bergman",
   "channel": "WEB",
   "totalPreTax": 96.53
 },
 {
  "id": "2854b9d6-9c42-11e5-8994-feff819cdc9f",
  "name": "Luis Borges",
  "channel": "IPAD",
  "totalPreTax": 119.0
}]

Пока у меня есть следующее (показаны только релевантные биты), которые сортируются по среднему значению totalPreTax:

{ //...
  "aggs": {
    "byCustomer": {
      "terms": {
        "field": "customer.id",
        "order": {
          "averageTotalPreTax": "desc"
        }
      },
      "aggs": {
        "averageTotalPreTax": {
          "avg": {
            "field": "totalPreTax"
          }
        },
        "channel": {
          "terms": {
            "field": "channel",
            "order": {
              "_term": "desc"
            },
            "size": 1
        }
    }
}

Проблема в том, что для определения верхних channel для каждой корзины (т. е. для каждого клиента) требуется вторая подагрегация term из нескольких корзин. Меня интересует только первый элемент этого результирующего массива, который содержит необходимое значение для наиболее частого канала. Это не позволяет мне сортировать мою агрегацию byCustomer, используя что-то вроде:

"byCustomer": {
      "terms": {
        "field": "customer.id",
        "order": {
          "channel": "desc"
        }
      }
}

В результате чего:

AggregationExecutionException[Недопустимый путь порядка агрегации терминов [канал]. Сегменты терминов можно сортировать только на пути субагрегатора, который состоит из нуля или более агрегаций отдельных сегментов в пути и конечного агрегирования одного сегмента или метрик в конце пути.

Кто-то решил нечто подобное (но не совсем мой сценарий), но не ответил должным образом на вопрос.

Итак, как мне это сделать? Любые идеи?

EDIT: вопрос не привязан к версии ES. Возможные ответы могут относиться к любой конкретной версии API.


person Nicolás Fantone    schedule 06.12.2015    source источник