Spec-Zone.ru › Elasticsearch 7
›Elasticsearch Guide [7.17] ›Поиск данных

Получение вложенных совпадений

Функции parent-join и nested позволяют возвращать документы, имеющие совпадения в другом контексте. В случае родитель/потомки, родительские документы возвращаются на основе совпадений в дочерних документах, или дочерние документы возвращаются на основе совпадений в родительских документах. В случае nested, документы возвращаются на основе совпадений во вложенных внутренних объектах.

В обоих случаях фактические совпадения в различных контекстах, которые привели к возврату документа, скрыты. Во многих случаях очень полезно знать, какие внутренние вложенные объекты (в случае nested) или дочерние/родительские документы (в случае родитель/потомки) вызвали возврат определенной информации. Для этого можно использовать функцию inner hits. Эта функция возвращает дополнительную информацию о вложенных совпадениях, которые привели к совпадению поиска в другом контексте, на каждый результат поиска в ответе.

Вложенные совпадения могут использоваться путем определения inner_hits определения в nested, has_child или has_parent запросе и фильтре. Структура выглядит следующим образом:

"<query>" : {
  "inner_hits" : {
    <inner_hits_options>
  }
}

Если inner_hits определено в запросе, который его поддерживает, то каждый результат поиска будет содержать inner_hits json-объект со следующей структурой:

"hits": [
  {
    "_index": ...,
    "_type": ...,
    "_id": ...,
    "inner_hits": {
      "<inner_hits_name>": {
        "hits": {
          "total": ...,
          "hits": [
            {
              "_type": ...,
              "_id": ...,
               ...
            },
            ...
          ]
        }
      }
    },
    ...
  },
  ...
]

Параметры

Вложенные совпадения поддерживают следующие параметры:

from

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

size

Максимальное количество совпадений, возвращаемых на каждый inner_hits. По умолчанию возвращаются три наиболее совпадающих результата.

sort

Способ сортировки вложенных совпадений по inner_hits. По умолчанию совпадения сортируются по рейтингу.

name

Имя, используемое для определения конкретного вложенного совпадения в ответе. Полезно, когда в одном запросе определено несколько вложенных совпадений. Значение по умолчанию зависит от типа запроса, в котором определено вложенное совпадение. Для запроса и фильтра has_child это тип дочернего элемента, для запроса и фильтра has_parent это тип родительского элемента, а для запроса и фильтра nested это путь вложенного элемента.

Вложенные совпадения также поддерживают следующие функции на уровне каждого документа:

  • Выделение
  • Объяснение
  • Поля поиска
  • Фильтр источника
  • Скриптовые поля
  • Поля значений документа
  • Включить версии
  • Включить номера последовательности и основные термины

Вложенные вложенные совпадения

Вложенные inner_hits могут использоваться для включения вложенных внутренних объектов как вложенных совпадений для результата поиска.

PUT test
{
  "mappings": {
    "properties": {
      "comments": {
        "type": "nested"
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "title": "Test title",
  "comments": [
    {
      "author": "kimchy",
      "number": 1
    },
    {
      "author": "nik9000",
      "number": 2
    }
  ]
}

POST test/_search
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "match": { "comments.number": 2 }
      },
      "inner_hits": {} 
    }
  }
}

Определение вложенных совпадений в запросе nested. Другие параметры определять не нужно.

Пример фрагмента ответа, который может быть сгенерирован из вышеуказанного запроса поиска:

{
  ...,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": ...,
        "inner_hits": {
          "comments": { 
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": 1.0,
              "hits": [
                {
                  "_index": "test",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "comments",
                    "offset": 1
                  },
                  "_score": 1.0,
                  "_source": {
                    "author": "nik9000",
                    "number": 2
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

Имя, используемое в определении вложенного совпадения в запросе поиска. Можно использовать пользовательский ключ с помощью параметра name.

Метаданные _nested в приведенном выше примере имеют решающее значение, поскольку они определяют, из какого внутреннего вложенного объекта произошло это вложенное совпадение. field определяет поле массива объектов, из которого происходит вложенное совпадение, а offset относительно его расположения в _source. Из-за сортировки и ранжирования фактическое расположение объектов совпадения в inner_hits обычно отличается от расположения вложенного внутреннего объекта.

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

Важное значение имеет по умолчанию, что _source, возвращаемый в совпадениях внутри inner_hits, относится к метаданным _nested. Таким образом, в приведенном выше примере возвращается только часть комментария для каждого вложенного совпадения, а не весь источник верхнего уровня документа, который содержал этот комментарий.

Вложенные вложенные совпадения и _source

Вложенные документы не имеют поля _source, поскольку весь источник документа хранится вместе с корневым документом в поле _source. Для включения источника только вложенного документа, источник корневого документа анализируется, и только соответствующая часть для вложенного документа включается в качестве источника в вложенном совпадении. Делать это для каждого совпадающего вложенного документа влияет на время выполнения всего запроса поиска, особенно когда size и size вложенных совпадений установлены выше, чем по умолчанию. Чтобы избежать относительно дорогостоящей экстракции источника для вложенных вложенных совпадений, можно отключить включение источника и полностью положиться на поля значений документов. Например так:

PUT test
{
  "mappings": {
    "properties": {
      "comments": {
        "type": "nested"
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "title": "Test title",
  "comments": [
    {
      "author": "kimchy",
      "text": "comment text"
    },
    {
      "author": "nik9000",
      "text": "words words words"
    }
  ]
}

POST test/_search
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "match": { "comments.text": "words" }
      },
      "inner_hits": {
        "_source": false,
        "docvalue_fields": [
          "comments.text.keyword"
        ]
      }
    }
  }
}

Иерархические уровни полей вложенного объекта и вложенные совпадения.

Если в схеме есть несколько уровней иерархических полей вложенных объектов, к каждому уровню можно получить доступ через точку с нотацией пути. Например, если есть вложенное поле comments, которое содержит вложенное поле votes и голоса должны быть возвращены непосредственно с корневыми результатами, то можно определить следующий путь:

PUT test
{
  "mappings": {
    "properties": {
      "comments": {
        "type": "nested",
        "properties": {
          "votes": {
            "type": "nested"
          }
        }
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "title": "Test title",
  "comments": [
    {
      "author": "kimchy",
      "text": "comment text",
      "votes": []
    },
    {
      "author": "nik9000",
      "text": "words words words",
      "votes": [
        {"value": 1 , "voter": "kimchy"},
        {"value": -1, "voter": "other"}
      ]
    }
  ]
}

POST test/_search
{
  "query": {
    "nested": {
      "path": "comments.votes",
        "query": {
          "match": {
            "comments.votes.voter": "kimchy"
          }
        },
        "inner_hits" : {}
    }
  }
}

Что будет выглядеть так:

{
  ...,
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 0.6931471,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.6931471,
        "_source": ...,
        "inner_hits": {
          "comments.votes": { 
            "hits": {
              "total" : {
                  "value": 1,
                  "relation": "eq"
              },
              "max_score": 0.6931471,
              "hits": [
                {
                  "_index": "test",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "comments",
                    "offset": 1,
                    "_nested": {
                      "field": "votes",
                      "offset": 0
                    }
                  },
                  "_score": 0.6931471,
                  "_source": {
                    "value": 1,
                    "voter": "kimchy"
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

Эта косвенная ссылка поддерживается только для вложенных вложенных совпадений.

Вложенные совпадения родитель/потомки

Вложенные совпадения родитель/потомки можно использовать для включения родительских или дочерних:

PUT test
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "my_parent": "my_child"
        }
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "number": 1,
  "my_join_field": "my_parent"
}

PUT test/_doc/2?routing=1&refresh
{
  "number": 1,
  "my_join_field": {
    "name": "my_child",
    "parent": "1"
  }
}

POST test/_search
{
  "query": {
    "has_child": {
      "type": "my_child",
      "query": {
        "match": {
          "number": 1
        }
      },
      "inner_hits": {}    
    }
  }
}

Определение вложенного совпадения, как и в примере с вложенными объектами.

Пример фрагмента ответа, который может быть сгенерирован из вышеуказанного запроса поиска:

{
  ...,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "number": 1,
          "my_join_field": "my_parent"
        },
        "inner_hits": {
          "my_child": {
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": 1.0,
              "hits": [
                {
                  "_index": "test",
                  "_type": "_doc",
                  "_id": "2",
                  "_score": 1.0,
                  "_routing": "1",
                  "_source": {
                    "number": 1,
                    "my_join_field": {
                      "name": "my_child",
                      "parent": "1"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/inner-hits.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API