Возвращаемое значение ключа из альтернативного поля в агрегировании

Можно ли заставить Elastic Search возвращать агрегированный ключ на основе другого поля документа?

Мы помещаем как иностранный идентификатор, так и иностранное имя в нашем типе, а затем агрегируем по id, но хотели бы вернуть имя. Имена не уникальны, поэтому они не подходят для агрегации. Я знаю, что они также не обязательно уникальны по сравнению с набором записей, но будут принимать имя, взятое из одной записи набора.

Например, наши данные касаются продаж продукта. Каждая продажа имеет идентификатор продукта и имя продукта, связанные с ним.

// Sales
{ "product_id": 1, "product_name": "Beer", "quantity": 3, … }
{ "product_id": 1, "product_name": "Beer", "quantity": 2, … }
{ "product_id": 2, "product_name": "Wine", "quantity": 6, … }

Query:

"aggregations": {
    "product": {
      "terms": {
        "field": "product_id"
      },
      "aggregations": {
        "day": {
          "count": {
            "value_count": {
              "field": "quantity"
            }
          }
        }
      }
    }
  }
}

Результат:

…
"aggregations": {
  "product": {
    "buckets": [
    {
      "key": "1",
      "doc_count": 2,
      "count": {
        "value": 5
      }
    },{
      "key": "2",
      "doc_count": 1,
      "count": {
        "value": 6
    }
    ]
  }
}
…

Требуемый результат:

…
"aggregations": {
  "product": {
    "buckets": [
    {
      "key": "Beer",
      "doc_count": 2,
      "count": {
        "value": 5
      }
    },{
      "key": "Wine",
      "doc_count": 1,
      "count": {
        "value": 6
    }
    ]
  }
}
…

После чтения документов на скриптах я не думаю, что это возможно, поскольку он оценивает только значение и, похоже, не имеет доступа ко всему документу (поскольку отсутствует документ, но набор документов).

Ответ 1

Вы можете сделать это со сценариями, если вы используете только атрибут script (тогда у него есть доступ ко всему документу). Затем разделите его на свой клиент: например.

"aggs": {
    "types_of": {
      "terms": {
        "script": "doc['product_name'].value + '|' + doc['product_id'].value"
      }
    }
  }

Ответ 2

Если у вас есть все полномочия над процессом индексации, я бы предложил просто добавить новое поле самостоятельно (не анализировалось) на основе product_id и вместо этого агрегировать в этом поле.

Я не думаю (но я могу ошибаться), что то, что вы хотите сделать, возможно.

Ответ 3

Вы можете использовать дочернюю агрегацию для получения имени, поэтому ваш запрос будет выглядеть примерно так:

"aggregations": {
    "product": {
      "terms": {
        "field": "product_id"
      },
      "aggregations": {
        "name": {
          "terms": {
            "field": "product_name"
          }
        },
        "day": {
          "count": {
            "value_count": {
              "field": "quantity"
            }
          }
        }
      }
    }
  }
}