Elasticsearch, агрегировать по значению поля массива

#elasticsearch #elasticsearch-aggregation

#elasticsearch #elasticsearch-агрегирование

Вопрос:

Мои документы выглядят так:

 [
    {
        'user_id': 1,
        'search_text': 'hi',
        'searched_departments': ["dep4", "dep5", "dep6"]
    },
    {
        'user_id': 1,
        'search_text': 'hi there',
        'searched_departments': ["dep4", "dep6"]
    },
    {
        'user_id': 5,
        'search_text': 'I like candy',
        'searched_departments': ["dep4", "dep11", "dep999"]
    },
    {
        'user_id': 2,
        'search_text': 'hi',
        'searched_departments': ["dep4", "dep6", "dep7"]
    }
]
 

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

 {
"dep4" : 4,
"dep6" : 3,
"dep5" : 1,
# and so on
}
 

мое отображение:

 {'mappings': {'properties': {'date': {'type': 'date'},
                             'searched_departments': {'type': 'text'},
                             'search_text': {'type': 'text'},
                             'user_id': {'type': 'text'}}}
 

Комментарии:

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

2. Обновлено @SagarPatel 🙂

Ответ №1:

Вы не можете получить агрегацию по текстовому типу поля (если вы все еще хотите генерировать агрегацию по текстовому типу поля, тогда поле должно быть включено с fielddata параметром to true ). Для получения агрегации вы можете определить searched_departments поле как многополевое с ключевым словом и текстом обоих типов.

Ниже приведен пример сопоставления:

 {
    "mappings": {
        "properties": {
            "date": {
                "type": "date"
            },
            "searched_departments": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "search_text": {
                "type": "text"
            },
            "user_id": {
                "type": "text"
            }
        }
    }
}
 

Затем приведенный ниже запрос даст вам ожидаемый результат:

 POST index_name/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "dept_count": {
      "terms": {
        "field": "searched_departments.keyword",
        "size": 10
      }
    }
  }
}