Вопрос или проблема
У меня есть индекс elasticsearch, который содержит следующие поля: user_id, agent_name, city, ...
Я хочу выполнить запрос для выбора записей, где agent_name
“agent1” является одним из агентов, но также есть и другие агенты, а затем выбрать тех, у кого агенты находятся более чем в 2 городах.
Я использовал следующий запрос:
query = {
"size": 0, # Не нужны сами документы, только результаты агрегации
"query": {
{"match": {agent_name: 'agent1'}
},
"aggs": {
"user_ids": {
"terms": {"field": "user_id", "size": 60000},
"aggs": {
"city_count": {"cardinality": {"field": "city"}}
}
}
},
}
В приведенном выше примере, если я выполню запрос, он сперва выберет записи, где все значения agent_name
равны ‘agent1’, затем агрегирует результат, таким образом, я получаю результат, если agent1
активен в 2 городах. Но я хочу, чтобы он выбирал запись, если один из его агентов – ‘agent1’, и также есть другие агенты, кроме agent1
. Как мне изменить часть query
, чтобы получить желаемый результат?
Ответ или решение
Чтобы выполнить запрос в Elasticsearch, который выбирает записи с agent_name
равным "agent1", но также учитывает записи с другими агентами для тех же пользователей, нужно изменить часть запроса так, чтобы отобрать документы, содержащие "agent1" среди других агентов. Для этого можно использовать запрос с bool
и must
для комбинации условий.
Вот как можно изменить ваш запрос:
{
"size": 0, # Не требуется возвращать фактические документы, только результаты агрегации.
"query": {
"bool": {
"must": [
{ "match": { "agent_name": "agent1" } } # Необходимо, чтобы один из агентов был 'agent1'.
],
"filter": {
"terms": {
"user_id": {
"index": "your_index", # Укажите ваш индекс.
"id": "_id", # Укажите идентификатор документа, если необходимо.
"path": "user_id"
}
}
}
}
},
"aggs": {
"user_ids": {
"terms": {
"field": "user_id",
"size": 60000
},
"aggs": {
"city_count": {
"cardinality": {
"field": "city"
}
},
"other_agents_filter": {
"bucket_selector": {
"buckets_path": {
"cityCount": "city_count"
},
"script": "params.cityCount > 2" # Фильтруем пользователей по количеству городов > 2.
}
}
}
}
}
}
Объяснение изменений:
-
Запрос
bool
: Мы используем запрос сbool
, чтобы требовать наличие "agent1" среди агентов. - Аггрегации:
terms
поuser_id
: Сохраняем группировку пользователей.cardinality
поcity
: Считаем количество уникальных городов для каждого пользователя.bucket_selector
: Добавляем этап фильтрации, который выбирает только те группы (пользователей), у которых количество уникальных городов больше 2.
Обратите внимание:
- В
terms
вfilter
вы можете настроить путь кuser_id
в зависимости от вашей структуры данных. - Этот запрос предполагает, что вы заинтересованы только в количестве пользователей, где "agent1" активен и которые имеют других агентов. Поддерживайте индексы актуальными и отлаживайте запрос с реальными данными для оптимальных результатов.