Spec-Zone.ru › Elasticsearch 7
›Elasticsearch Guide [7.17] ›Отображение ›Типы данных полей

Тип поля 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"
    }
  ]
}

Поле user динамически добавляется как поле типа object.

Предыдущий документ будет внутренне преобразован в документ, который выглядит примерно так:

{
  "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": {}
          }
        }
      }
    }
  }
}

Поле user отображается как тип nested вместо типа object.

Этот запрос не соответствует, потому что Alice и Smith не находятся в одном вложенном объекте.

Этот запрос соответствует, потому что Alice и White находятся в одном вложенном объекте.

inner_hits позволяют выделить соответствующие вложенные документы.

Взаимодействие с документами 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

Spec-Zone.ru

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