Elasticsearch: Нахождение перекрытия одного поля против другого - PullRequest
1 голос
/ 03 марта 2020

Я пытаюсь найти способ сделать это в Elasticsearch, не делая несколько запросов, или используя _mget, если необходимо.

У меня много документов с такой структурой:

{
  'location': 'Orlando',
  'agent_id': 395205, 
},
{
  'location': 'Miami',
  'agent_id': 391773,
},
{
  'location': 'Miami',
  'agent_id': 391773,
},
{
  'location': 'Tampa',
  'agent_id': 395205,
}

Там, где есть фиксированное количество location значений, но много уникальных agent_id s.

Моя конечная цель, учитывая список местоположений, найти agent_id s, которые существуют во всех из них. Таким образом, в приведенном выше примере, учитывая ['Orlando', 'Tampa'], мы получаем [395205] назад, потому что он существует в обоих. Одно местоположение МОЖЕТ иметь дубликаты agent_id с (и это ожидаемое поведение), поэтому я не могу использовать счетчики (например, показать мне agent_id с, которые появляются n раз, где n = len(locations).

Еще один ключ здесь заключается в том, что я хотел бы на самом деле возвращать попадания, если это возможно, а не в совокупном ведре. Так что в идеале top_hits может быть где-то вложено.

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

1 Ответ

1 голос
/ 06 марта 2020

Количество уникальных местоположений в агенте может использоваться для поиска общих агентов

Запрос:

{
  "query": { --> select docs with give location
    "terms": {
      "location.keyword": [
        "Orlando",
        "Tampa"
      ]
    }
  },
  "aggs": {
    "agents": {
      "terms": {
        "field": "agent_id",  ---> List of agents
        "size": 10
      },
      "aggs": {
        "location": {         ---> Unique locations under a agent
          "terms": {
            "field": "location.keyword",
            "size": 10
          }
        },
        "my_bucket": {
          "bucket_selector": {
            "buckets_path": {
              "count": "location._bucket_count" 
            },
            "script": "params.count==2" -->count of locations for agent, replace 2
                                        --> with needed count(number of locations)
          }
        }
      }
    }
  }
}

Результат:

 [
      {
        "_index" : "index30",
        "_type" : "_doc",
        "_id" : "LXuksHABg1vns4B5FWL5",
        "_score" : 1.0,
        "_source" : {
          "location" : "Orlando",
          "agent_id" : 395205
        }
      },
      {
        "_index" : "index30",
        "_type" : "_doc",
        "_id" : "MHuksHABg1vns4B5OmKC",
        "_score" : 1.0,
        "_source" : {
          "location" : "Tampa",
          "agent_id" : 395205
        }
      }
    ]
  },
  "aggregations" : {
    "agents" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 395205,
          "doc_count" : 2,
          "location" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Orlando",
                "doc_count" : 1
              },
              {
                "key" : "Tampa",
                "doc_count" : 1
              }
            ]
          }
        }
      ]
    }
  }
...