Составная группа Elasticsearch по запросам по документам - PullRequest
0 голосов
/ 22 февраля 2020

У нас есть elasti c поисковый документ, размер которого называется городом. Каждый документ будет иметь только одно значение для поля города. У меня есть сценарий, в котором мне нужно запросить человека по городу или городам.

Документы в Elasticsearch

{
  person_id: "1",
  property_value : 25000,
  city: "Bangalore"
}
{
  person_id: "2",
  property_value : 100000,
  city: "Bangalore"
}
{
  person_id: "1",
  property_value : 15000,
  city: "Delhi"
}

Примечание : Агрегация должна выполняться для property_value и группироваться по person_id.

Например,

  1. Если я запрашиваю Бангалор, он должен вернуть документ с person_id 1 и 2.
  2. Если я запрашиваю и Дели, и Бангалор, он должен вернуть это

    {person_id: "1", property_value: 40000, city: ["Bangalore", "Delhi"]}}

1 Ответ

1 голос
/ 22 февраля 2020

Глядя на ваши данные, я пришел с образцом сопоставления, запросом запроса и ответом.

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

PUT my_index_city
{
  "mappings": {
    "properties": {
      "person_id":{
        "type": "keyword"
      },
      "city":{
        "type":"text",
        "fields":{
          "keyword":{       
            "type": "keyword"
          }
        }
      },
      "property_value":{
        "type": "long"
      }
    }
  }
}

Пример запроса:

Обратите внимание, что я использовал простую строку запроса для фильтрации документов, имеющих Бангалор и Дели.

Для агрегации я использовал Термины агрегации в person_id и Сумма агрегации в поле property_value.

POST my_index_city/_search
{
  "size": 0, 
  "query": {
    "query_string": {
      "default_field": "city",
      "query": "Bangalore Delhi"
    }
  },
  "aggs": {
    "my_person": {
      "terms": {
        "field": "person_id",
        "size": 10,
        "min_doc_count": 2
      },
      "aggs": {
        "sum_property_value": {
          "sum": {
            "field": "property_value"
          }
        }
      }
    }
  }
}

Пример ответа:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "my_person" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "1",
          "doc_count" : 2,
          "sum_property_value" : {
            "value" : 40000.0
          }
        }
      ]
    }
  }
}

Примечание: Этот запрос будет работать, только если person_id имеет несколько документов , но каждый документ, имеющий уникальное / другое значение города.

Я хочу сказать, что если person_id имеет несколько документов с одним и тем же городом, объединение не даст правильного ответа.

Обновленный ответ:

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

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

PUT my_sample_city_index
{
  "mappings": {
    "properties": {
      "person_id":{
        "type": "keyword"
      },
      "property_details":{
        "type":"nested",               <------ Note this
        "properties": {
          "city":{
            "type": "text",
            "fields":{
              "keyword":{
                "type":"keyword"
              }
            }
          },
          "property_value":{
            "type": "long"
          }
        }
      }
    }
  }
}

Образцы документов:

POST my_sample_city_index/_doc/1
{
  "person_id": "1",
  "property_details":[
    {
      "property_value" : 25000,
      "city": "Bangalore"
    },
    {
      "property_value" : 15000,
      "city": "Delhi"
    }
    ]
}

POST my_sample_city_index/_doc/2
{
  "person_id": "2",
  "property_details":[
    {
      "property_value" : 100000,
      "city": "Bangalore"
    }
    ]
}

Запрос агрегации:

POST my_sample_city_index/_search
{
  "size": 0,
  "query": {
    "nested": {
      "path": "property_details",
      "query": {
        "query_string": {
          "default_field": "property_details.city",
          "query": "bangalore delhi"
        }
      }
    }
  },
  "aggs": {
    "persons": {
      "terms": {
        "field": "person_id",
        "size": 10
      },
      "aggs": {
        "property_sum": {
          "nested": {                          <------ Note this
            "path": "property_details"
          },
          "aggs": {
            "total_sum": {
              "sum": {
                "field": "property_details.property_value"
              }
            }
          }
        }
      }
    }
  }
}

Обратите внимание, что я первоначально применил запрос термина к person_id сообщению, к которому применил Вложенная агрегация , далее который я применил метри c сумма агрегации запрос.

Это также должно работать правильно, если у человека есть несколько свойств в одном городе.

Ответ:

{
  "took" : 31,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "persons" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "1",
          "doc_count" : 1,
          "property_sum" : {
            "doc_count" : 2,
            "total_sum" : {
              "value" : 40000.0
            }
          }
        },
        {
          "key" : "2",
          "doc_count" : 1,
          "property_sum" : {
            "doc_count" : 1,
            "total_sum" : {
              "value" : 100000.0
            }
          }
        }
      ]
    }
  }
}

Дайте мне знать, если это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...