Elasticsearch Learning — документация для родителей и детей

Elasticsearch

В этой статье в качестве примера используется Elasticsearch версии 6.8.4, чтобы представить использование родительско-дочерних документов Elasticsearch.

image

В предыдущей статье были представлены вложенные документы Elasticsearch, а в этой статье представлен еще один тип реляционных документов, родительско-дочерний документ.

1. Документы родителей и детей

С точки зрения понимания документ «родитель-потомок» можно понимать как ассоциативный запрос, который чем-то похож на запрос JOIN в MySQL, который связан через отношение полей.

Основное различие между родительско-дочерними документами и вложенными документами заключается в том, что родительский и дочерний объекты родительско-дочерних документов являются независимыми документами, а вложенные документы хранятся в одном и том же документе, как показано на следующем рисунке:

image

Цитируя официальный сайт здесь, основными преимуществами отношений родитель-потомок по сравнению с вложенными документами являются:

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

1.1 Создайте индекс

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

[
    {
        "title":"这是一篇文章",
        "body":"这是一篇文章,从哪里说起呢? ... ..."
    },
    {
        "name":"张三",
        "comment":"写的不错",
        "age":28,
        "date":"2020-05-04"
    },
    {
        "name":"李四",
        "comment":"写的很好",
        "age":20,
        "date":"2020-05-04"
    },
    {
        "name":"王五",
        "comment":"这是一篇非常棒的文章",
        "age":31,
        "date":"2020-05-01"
    }
]

Создайте индекс с именем индекса и типом блога.Как видно из приведенных выше данных, на самом деле родительский документ (содержимое блога) и дочерний документ используют разные поля для хранения соответствующих данных, но при создании индекса документ, необходимо указать родительский и дочерний документы.Отношение, то есть статья является родительским, сообщение является дочерним, а оператор создания индекса выглядит следующим образом:

PUT http://localhost:9200/blog/

{
  "mappings": {
    "blog": {
      "properties": {
        "date": {
          "type": "date"
        },
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "comment": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "age": {
          "type": "long"
        },
        "body": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "title": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "relation": {
          "type": "join",
          "relations": {
            "parent": "child"
          }
        }
      }
    }
  }
}

Как показано ниже

image

1.2 Вставка данных

Чтобы вставить данные родительского документа, вам нужно указать отношение в структуре индекса выше как родительское, как показано ниже:

POST http://localhost:9200/blog/blog/1/

{
    "title":"这是一篇文章",
    "body":"这是一篇文章,从哪里说起呢? ... ...",
    "relation":"parent"
}

Чтобы вставить вложенный документ, вам нужно использовать параметр маршрутизации в адресе запроса, чтобы указать, чей вложенный документ, и указать отношение в структуре индекса следующим образом:

POST http://localhost:9200/blog/blog/2?routing=1

{
    "name":"张三",
    "comment":"写的不错",
    "age":28,
    "date":"2020-05-04",
    "relation":{
        "name":"child",
        "parent":1
    }
}

POST http://localhost:9200/blog/blog/3?routing=1

{
    "name":"李四",
    "comment":"写的很好",
    "age":20,
    "date":"2020-05-04",
    "relation":{
        "name":"child",
        "parent":1
    }
}

POST http://localhost:9200/blog/blog/4?routing=1

{
    "name":"王五",
    "comment":"这是一篇非常棒的文章",
    "age":31,
    "date":"2020-05-01",
    "relation":{
        "name":"child",
        "parent":1
    }
}

После завершения вставки, как показано на рисунке ниже.

image

Отсюда хорошо видно отличие от вложенных документов, во вложенном документе всего один документ, а здесь четыре документа.

1.3 Запрос

Общие запросы здесь не повторяются, но реляционные запросы на самом деле очень просты для понимания и могут быть грубо разделены на два особых случая:

  1. Запросить дочерний документ has_child на основе родительского документа
  2. Запрос родительского документа has_parent на основе дочернего документа

Далее давайте посмотрим, как запросить связь. Сначала давайте посмотрим на запрос родительского документа через поддокумент. Например, в этом сценарии имя запроса — это статья, оставленная человеком Чжан Саня. составляет:

{
  "query": {
    "has_child": {
      "type":"child",
      "query": {
        "match": {
          "name": "张三"
        }
      }
    }
  }
}

Результаты запроса следующие:

image

Используйте has_child для запроса родительского документа на основе содержимого дочернего документа.Фактически тип является идентификатором дочернего документа при его создании.

При использовании дочернего элемента для проверки родителя вы можете добавить некоторые условия фильтра для улучшения результатов сопоставления, например, максимальное совпадение max_children и минимальное соответствие min_children, что аналогично минимальному_should_match запроса. можно перейти на официальный сайт для более подробной информации.

На этом этапе читатели, знакомые с функциями Elasticsearch, будут знать, как запрашивать дочерние документы на основе родительского документа.Только нужно обратить внимание на один момент.Тип родительского запроса нужно изменить на parent_type, а остальные аналогичны родитель самопроверки, такой как заголовок запроса «Это содержание сообщения данных статьи», оператор запроса выглядит следующим образом:

{
  "query": {
    "has_parent": {
      "parent_type":"parent",
      "query": {
        "match": {
          "title": "这是一篇文章"
        }
      }
    }
  }
}

Результаты запроса следующие:

image

Поскольку есть только один набор родительских и дочерних документов, эффект не очень очевиден.Если вам интересно, вы можете создать больше данных, чтобы испытать

Агрегированные запросы аналогичны вложенным документам и относительно просты.Вот еще один сценарий: можно ли создать бабушек и дедушек и внуков? Например, если сообщение в этой статье также имеет вложенные документы, можно ли запрашивать внуков на основе статьи? Ответ — да, вам нужно только вложить запрос has_child в has_child.

1.4 Рекомендации по использованию

  1. И родительский, и дочерний документы могут быть возвращены независимо друг от друга, что очень удобно для некоторых сценариев.Например, информация основной таблицы представляет собой некоторые в основном неизмененные данные, в то время как информация дочерней таблицы часто добавляется, удаляется и изменяется, а информация дочерней таблицы часто имеет сценарии запросов, поэтому очень удобно использовать документы родитель-потомок.
  2. Родительский и дочерний документы должны быть на одном осколке.Конечно особой обработки делать не нужно.По умолчанию мы поставим один и тот же осколок для меня.На самом деле принцип такой.Elasticsearch увидит где родительский документ располагается по параметрам в маршрутизации, а затем сохраняет в нем соответствующий документ.
  3. Эффективность запроса родительско-дочерних документов ниже, чем у вложенных документов, и, по официальному сайту, примерно в 5-10 раз.

Остальная часть официального сайта также дает некоторые предложения, вы можете проверить официальные документы для получения подробной информации, адрес:woohoo.elastic.co/дорогой/талантливый/плохой…