Возвращает только один элемент из массива strings в elasticsearch


У меня есть массив строк в одном поле "strArray":

strArray: ['browser:IE', 'device:PC', 'country:USA', 'state:CA']

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

Я мог бы использовать те структуры:

"aggs": {
  "deviceAggs": {
    "terms": {
      "script": "doc['strArray'][1]"
    }
  }
}
Но проблема в том, что порядок вставки этих строк может быть разным.

Как я могу это сделать ? Я думаю о нескольких способах:

  1. Scripting-использовать функцию типа как подстроку и получить только " правильный" ценности.

  2. Фильтрация-можно отфильтровать одно значение (содержащее строку "device:") из массива.

  3. Сортировка strArray значений позволяет расположить все значения в определенном порядке, но "сортировка" дает странный результат - возвращает только один элемент (без какой-либо фильтрации).

Не спрашивайте меня, почему у меня есть эта структура (это не мой выбор), если у нас есть структура key: value - у нас не было бы проблем.

1 2

1 ответ:

Скриптинг здесь возможен только напрямую. Чтобы получить представление о том, как использовать сценарии в агрегациях, вы можете обратиться к этому блогу .

Что-то вроде ниже должно работать

for(element in doc['strArray'].values){
      if(element.startsWith('browser')){
          return element;
      }
};
return null;

И сортировка, и фильтрация выполняются на уровне документа,а не элемента. На уровне элементов , если вы можете сделать этот массив вложенным, возможна фильтрация. То есть сначала нужно изменить структуру на -

strArray: [
  { "name" : 'browser:IE' } , 
  { "name" : 'device:PC' } 
 ]

И затем сделайте поле strArray вложенным. В этом случае вы можете сделать вложенный фильтр на основе префиксного запроса (с помощью фильтра запросов), а затем выполните вложенную агрегацию данных.