В предыдущем уроке мы говорили о простых типах данных. В этом уроке мы поговорим о том, как установить схему для массивов, объектов и вложенных объектов.
Массив
Для массива нет специального типа данных. Давайте посмотрим на примере:
Документ 1:
{ "keyword_field" : "keyword1" }
Документ 2:
{
"keyword_field" : ["keyword2", "keyword3"]
}
Схему надо определить так:
{ "properties": { "keyword_field": { "type": "keyword" } } }
Для массивов не требуется специальная обработка.
Объект
Документы Elasticsearch являются объектами JSON. Поле в документе может быть как просто числом, так и целым объектом. Например, документ пользователя, как показано ниже, содержит имя, которое представляет собой простое текстовое поле и адрес, который является объектом. А адрес также может иметь внутренние объекты. Объект пользователя:
{
"id": 1,
"name": "Петр",
"address": {
"street": "Ленина 19б",
"city": "Москва"
}
}
В отличие от простых типов данных, когда объект сохраняется в инвертированном индексе, он разбивается на пары «ключ-значение». Документ пользователя хранится, как показано ниже:
{
"id": 1,
"name": "User1",
"address.street": "Ленина 19б",
"address.city": "Москва"
}
Поскольку объект хранится в виде пар ключ-значение, он становится сложным, когда у вас есть массив объектов. Посмотрим, что произойдет, если у пользователя несколько адресов. Например:
{
"id": 1,
"name": "User1",
"address": [
{
"street": "Сивкова 12",
"city": "Васьково"
},
{
"street" : "Русталова 2",
"city": "Москва"
}
}
Храниться он будет следующим образом:
{
"id" : 1,
"name" : "User1",
"address.street" : ["Сивкова 12", "Русталова 2"]
"address.city" : ["Васьково", "Москва"]
}
Когда объекты адреса хранятся в инвертированном индексе, связь между частями одного и того же адреса теряется. Например, если вы запрашиваете все документы, содержащие улицу, Сивкова 12
и Москва
, глядя на исходный документ, результатов не должно быть. Но учитывая способ хранения документ все же вернется. Если вашему приложению необходимо не повреждать отношение, вы должны использовать вложенный тип данных, о котором мы поговорим в следующем разделе.
Вы можете установить схему, как показано ниже:
{
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "keyword"
},
"address": {
"properties": {
"street": {
"type": "keyword"
},
"city": {
"type": "keyword"
}
}
}
}
}
Обратите внимание, что для массива адресов (объектов) нет специального сопоставления.
Вложенные
Как мы обсуждали в предыдущем разделе, когда у нас есть массив объектов, массив сглаживается, из-за чего отношения между полями объектов ломаются. Чтобы решить эту проблему, Elasticsearch предоставляет вложенный тип данных. Когда вы используете вложенный тип данных, каждый объект в массиве индексируется как новый вложенный документ. Поскольку объекты обрабатываются внутри как отдельные документы, вам нужно использовать специальный тип запроса для запроса вложенных документов. Мы обсудим вложенные запросы и сортировку в 7 уроке.
Настройка маппинга для вложенных типов данных:
{ "properties": { "id": { "type": "integer" }, "name": { "type": "keyword" }, "address_nested": { "type": "nested", "properties": { "street": { "type": "keyword" }, "city": { "type": "keyword" } } } } }