Тип поля nested
Тип nested — это специализированная версия типа данных object, которая позволяет индексировать массивы объектов таким образом, что к ним можно обращаться независимо друг от друга.
При обработке пар ключ-значение с большим и произвольным набором ключей, можно рассмотреть возможность моделирования каждой пары ключ-значение как отдельного вложенного документа с полями key и value. Вместо этого, рассмотрите использование типа данных flattened, который отображает весь объект как одно поле и позволяет выполнять простые поиски по его содержимому. Вложенные документы и запросы обычно требуют больших затрат ресурсов, поэтому использование типа данных flattened в данном случае является лучшим вариантом.
Как массивы объектов сглаживаются
Elasticsearch не имеет понятия вложенных объектов. Поэтому он сглаживает иерархии объектов в простой список имён и значений полей. Например, рассмотрите следующий документ:
PUT my-index-000001/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
} | Поле |
Предыдущий документ будет внутренне преобразован в документ, который выглядит примерно так:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
} Поля user.first и user.last сглаживаются в поля с множественными значениями, и связь между alice и white теряется. Этот документ некорректно соотнесёт запрос на alice AND smith:
GET my-index-000001/_search
{
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
} Использование полей nested для массивов объектов
Если вам нужно индексировать массивы объектов и сохранить независимость каждого объекта в массиве, используйте тип данных nested вместо типа данных object.
Внутренне, вложенные объекты индексируют каждый объект в массиве как отдельный скрытый документ, что означает, что к каждому вложенному объекту можно обращаться независимо от других с помощью запроса nested:
PUT my-index-000001
{
"mappings": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
PUT my-index-000001/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
}
}
GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }}
]
}
},
"inner_hits": {
"highlight": {
"fields": {
"user.first": {}
}
}
}
}
}
} | Поле | |
| Этот запрос не соответствует, потому что | |
| Этот запрос соответствует, потому что | |
|
|
Взаимодействие с документами nested
Вложенные документы могут:
- быть запрошены с помощью запроса
nested. - быть проанализированы с помощью агрегаций
nestedиreverse_nested. - быть отсортированы с помощью сортировки вложенных объектов.
- быть получены и выделены с помощью вложенных внутренних совпадений.
Поскольку вложенные документы индексируются как отдельные документы, к ним можно получить доступ только в рамках запроса nested, агрегаций nested/reverse_nested или вложенных внутренних совпадений.
Например, если строковое поле внутри вложенного документа имеет index_options установленное в offsets, чтобы разрешить использование позиций при выделении, эти смещения не будут доступны во время основной фазы выделения. Вместо этого, выделение должно выполняться с помощью вложенных внутренних совпадений. Та же самая рекомендация применяется при загрузке полей во время поиска с помощью docvalue_fields или stored_fields.
Параметры для полей nested
Следующие параметры принимаются полями nested:
-
dynamic - (Необязательно, строка) Указывает, нужно ли добавлять новые
propertiesдинамически к существующему вложенному объекту. Принимает значенияtrue(по умолчанию),falseиstrict. -
properties - (Необязательно, объект) Поля внутри вложенного объекта, которые могут быть любого типа данных, включая
nested. Новые свойства могут быть добавлены к существующему вложенному объекту.
-
include_in_parent - (Необязательно, Булево) Если
true, все поля вложенного объекта также добавляются в родительский документ как стандартные (плоские) поля. По умолчаниюfalse.
-
include_in_root - (Необязательно, Булево) Если
true, все поля вложенного объекта также добавляются в корневой документ как стандартные (плоские) поля. По умолчаниюfalse.
Ограничения на отображения и объекты nested
Как описано ранее, каждый вложенный объект индексируется как отдельный документ Lucene. Продолжая предыдущий пример, если мы индексируем один документ, содержащий 100 объектов user, то будет создано 101 документ Lucene: один для родительского документа и один для каждого вложенного объекта. Из-за затрат, связанных с отображениями nested, Elasticsearch устанавливает настройки для предотвращения проблем с производительностью:
-
index.mapping.nested_fields.limit - Максимальное количество различных отображений
nestedв индексе. Типnestedследует использовать только в особых случаях, когда массивы объектов необходимо запрашивать независимо друг от друга. Для защиты от плохо спроектированных отображений данная настройка ограничивает количество уникальных типовnestedна индекс. По умолчанию50.
В предыдущем примере отображение user будет учитываться только как 1 в этом ограничении.
-
index.mapping.nested_objects.limit - Максимальное количество вложенных JSON-объектов, которые может содержать один документ во всех типах
nested. Это ограничение помогает предотвратить ошибки исчерпания памяти, когда документ содержит слишком много вложенных объектов. По умолчанию10000.
Чтобы проиллюстрировать, как работает эта настройка, добавьте еще один тип nested под названием comments в предыдущее отображение. Для каждого документа общее количество объектов user и comment, которые он содержит, должно быть ниже предела.
См. Настройки для предотвращения взрыва отображения в отношении дополнительных настроек для предотвращения взрыва отображений.
© 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/nested.html