Эластичный запрос Elasticsearch для выбора записей, где agent1 является одним из агентов, но также присутствуют и другие агенты.

Вопрос или проблема

У меня есть индекс 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.
                    }
                }
            }
        }
    }
}

Объяснение изменений:

  1. Запрос bool: Мы используем запрос с bool, чтобы требовать наличие "agent1" среди агентов.

  2. Аггрегации:
    • terms по user_id: Сохраняем группировку пользователей.
    • cardinality по city: Считаем количество уникальных городов для каждого пользователя.
    • bucket_selector: Добавляем этап фильтрации, который выбирает только те группы (пользователей), у которых количество уникальных городов больше 2.

Обратите внимание:

  • В terms в filter вы можете настроить путь к user_id в зависимости от вашей структуры данных.
  • Этот запрос предполагает, что вы заинтересованы только в количестве пользователей, где "agent1" активен и которые имеют других агентов. Поддерживайте индексы актуальными и отлаживайте запрос с реальными данными для оптимальных результатов.
Оцените материал
Добавить комментарий

Капча загружается...