Фильтрация вложенных объектов в ElasticSearch 6.8.1 - PullRequest
0 голосов
/ 20 марта 2020

Я не нашел ответов, как сделать простую вещь в ElasticSearch 6.8 Мне нужно отфильтровать вложенные объекты.

Индекс

{
  "settings": {
    "index": {
      "number_of_shards": "5",
      "number_of_replicas": "1"
    }
  },
  "mappings": {
    "human": {
      "properties": {
        "cats": {
          "type": "nested",
          "properties": {
            "name": {
              "type": "text"
            },
            "breed": {
              "type": "text"
            },
            "colors": {
              "type": "integer"
            }
          }
        },
        "name": {
          "type": "text"
        }
      }
    }
  }
}

Данные

{
  "name": "iridakos",
  "cats": [
    {
      "colors": 1,
      "name": "Irida",
      "breed": "European Shorthair"
    },
    {
      "colors": 2,
      "name": "Phoebe",
      "breed": "european"
    },
    {
      "colors": 3,
      "name": "Nino",
      "breed": "Aegean"
    }
  ]
}

выберите человека с именем = "iridakos", а кошки с породой содержат "европейский" (игнорировать регистр). Только две кошки должны быть возвращены.

Миллион спасибо за помощь.

Ответы [ 2 ]

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

Для вложенных типов данных вам необходимо использовать nested queries.

Elasticsearch всегда возвращает весь документ в качестве ответа. Обратите внимание, что nested тип данных означает, что каждый элемент в списке будет рассматриваться как entire document сам по себе.

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

Ниже запроса должен помочь вам.

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "iridakos"
          }
        },
        {
          "nested": {
            "path": "cats",
            "query": {
              "match": {
                "cats.breed": "european"
              }
            },
            "inner_hits": {}
          }
        }
      ]
    }
  }
}

Ответ:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.74455214,
    "hits" : [
      {
        "_index" : "my_cat_index",
        "_type" : "_doc",
        "_id" : "1",                           <--- The document that hit
        "_score" : 0.74455214,
        "_source" : {
          "name" : "iridakos",
          "cats" : [
            {
              "colors" : 1,
              "name" : "Irida",
              "breed" : "European Shorthair"
            },
            {
              "colors" : 2,
              "name" : "Phoebe",
              "breed" : "european"
            },
            {
              "colors" : 3,
              "name" : "Nino",
              "breed" : "Aegean"
            }
          ]
        },
        "inner_hits" : {                       <---- Note this
          "cats" : {
            "hits" : {
              "total" : {
                "value" : 2,                   <---- Count of nested doc hits
                "relation" : "eq"
              },
              "max_score" : 0.52354836,
              "hits" : [
                {
                  "_index" : "my_cat_index",
                  "_type" : "_doc",
                  "_id" : "1",
                  "_nested" : {
                    "field" : "cats",
                    "offset" : 1
                  },
                  "_score" : 0.52354836,
                  "_source" : {                       <---- First Nested Document 
                    "breed" : "european"              
                  }
                },
                {
                  "_index" : "my_cat_index",
                  "_type" : "_doc",
                  "_id" : "1",
                  "_nested" : {
                    "field" : "cats",
                    "offset" : 0
                  },
                  "_score" : 0.39019167,
                  "_source" : {                       <---- Second Document
                    "breed" : "European Shorthair"
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

Отметьте в своем ответе, как появится раздел inner_hits, где вы найдете точные попадания.

Надеюсь, это поможет!

0 голосов
/ 20 марта 2020

Вы можете использовать что-то вроде этого:

{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "name":   "iridakos" }},
        { "match": { "cats.breed": "European" }}
      ]
    }
  }
}

Для поиска по породе кошки вы можете использовать точечную запись.

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