Извлечение выбранных полей из поиска
По умолчанию каждый результат поиска включает поле документа _source, которое представляет собой весь JSON-объект, предоставленный при индексировании документа. Рекомендуются два метода извлечения выбранных полей из запроса поиска:
Вы можете использовать оба этих метода, хотя параметр fields предпочтительнее, потому что он учитывает как данные документа, так и отображения индекса. В некоторых случаях вам может потребоваться использовать другие методы извлечения данных.
Параметр fields
Для извлечения определённых полей в ответе поиска используйте параметр fields. Поскольку он использует отображения индекса, параметр fields предоставляет несколько преимуществ по сравнению с прямым обращением к полю _source. В частности, параметр fields:
- Возвращает каждое значение стандартизированным способом, соответствующим его типу отображения
- Принимает множественные поля и псевдонимы полей
- Форматирует даты и пространственные типы данных
- Извлекает значения вычисляемых полей
- Возвращает поля, вычисленные скриптом во время индексирования
Также учитываются другие параметры отображения, включая ignore_above, ignore_malformed и null_value.
Параметр fields возвращает значения в соответствии с тем, как Elasticsearch их индексирует. Для стандартных полей это означает, что параметр fields ищет значения в _source, затем анализирует и форматирует их с использованием отображений.
Извлечение определённых полей
Следующий запрос поиска использует параметр fields для извлечения значений для поля user.id, всех полей, начинающихся с http.response., и поля @timestamp.
Используя нотацию объектов, вы можете передать аргумент format для настройки формата возвращаемых значений дат или геопространственных данных.
POST my-index-000001/_search
{
"query": {
"match": {
"user.id": "kimchy"
}
},
"fields": [
"user.id",
"http.response.*",
{
"field": "@timestamp",
"format": "epoch_millis"
}
],
"_source": false
} | Принимаются полные имена полей и шаблоны подстановок. | |
| Используйте параметр |
По умолчанию поля метаданных документа, такие как _id или _index, не возвращаются, когда запрашиваемый параметр fields использует шаблоны подстановок, такие как *. Однако при явном запросе с использованием имени поля можно получить доступ к полям метаданных _id, _routing, _ignored, _index и _version.
Ответ всегда возвращает массив
Ответ fields всегда возвращает массив значений для каждого поля, даже если в поле _source содержится единственное значение. Это связано с тем, что в Elasticsearch нет отдельного типа массива, и любое поле может содержать несколько значений. Параметр fields также не гарантирует, что значения массива будут возвращены в определённом порядке. Дополнительную информацию см. в документации по отображению массивов.
Ответ включает значения как плоский список в разделе fields для каждого результата поиска. Поскольку параметр fields не извлекает целые объекты, возвращаются только листовые поля.
{
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "0",
"_score" : 1.0,
"_type" : "_doc",
"fields" : {
"user.id" : [
"kimchy"
],
"@timestamp" : [
"4098435132000"
],
"http.response.bytes": [
1070000
],
"http.response.status_code": [
200
]
}
}
]
}
} Извлечение вложенных полей
Подробности
Ответ fields для nested полей немного отличается от ответов на обычные объектные поля. В то время как листовые значения внутри обычных object полей возвращаются как плоский список, значения внутри nested полей группируются для сохранения независимости каждого объекта внутри исходного вложенного массива. Для каждой записи внутри массива вложенного поля значения снова возвращаются как плоский список, если нет других nested полей внутри родительского вложенного объекта, в этом случае та же процедура повторяется для более глубоко вложенных полей.
Учитывая следующее отображение, где user - это вложенное поле, после индексирования следующего документа и извлечения всех полей под полем user:
PUT my-index-000001
{
"mappings": {
"properties": {
"group" : { "type" : "keyword" },
"user": {
"type": "nested",
"properties": {
"first" : { "type" : "keyword" },
"last" : { "type" : "keyword" }
}
}
}
}
}
PUT my-index-000001/_doc/1?refresh=true
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
POST my-index-000001/_search
{
"fields": ["*"],
"_source": false
} Ответ сгруппирует first и last имя, а не вернёт их как плоский список.
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [{
"_index": "my-index-000001",
"_id": "1",
"_score": 1.0,
"_type": "_doc",
"fields": {
"group" : ["fans"],
"user": [{
"first": ["John"],
"last": ["Smith"]
},
{
"first": ["Alice"],
"last": ["White"]
}
]
}
}]
}
} Вложенные поля будут сгруппированы по их вложенным путям, независимо от используемого шаблона для их извлечения. Например, если вы запросите только поле user.first из предыдущего примера:
POST my-index-000001/_search
{
"fields": ["user.first"],
"_source": false
} Ответ возвращает только имя пользователя, но всё ещё сохраняет структуру вложенного массива user.
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [{
"_index": "my-index-000001",
"_id": "1",
"_score": 1.0,
"_type": "_doc",
"fields": {
"user": [{
"first": ["John"]
},
{
"first": ["Alice"]
}
]
}
}]
}
} Однако, когда шаблон fields напрямую нацелен на вложенное поле user, значения не будут возвращены, потому что шаблон не соответствует ни одному из листовых полей.
Извлечение неотображённых полей
Подробности
По умолчанию параметр fields возвращает только значения отображённых полей. Однако Elasticsearch позволяет хранить поля в _source, которые не отображаются, например, установив динамическое отображение поля на false или используя объектное поле с enabled: false. Эти параметры отключают анализ и индексирование содержимого объекта.
Для извлечения неотображённых полей в объекте из _source используйте параметр include_unmapped в разделе fields:
PUT my-index-000001
{
"mappings": {
"enabled": false
}
}
PUT my-index-000001/_doc/1?refresh=true
{
"user_id": "kimchy",
"session_data": {
"object": {
"some_field": "some_value"
}
}
}
POST my-index-000001/_search
{
"fields": [
"user_id",
{
"field": "session_data.object.*",
"include_unmapped" : true
}
],
"_source": false
} | Отключить все отображения. | |
| Включить неотображённые поля, соответствующие этому шаблону поля. |
Ответ будет содержать результаты полей под путём session_data.object.*, даже если поля не отображены. Поле user_id также не отображается, но не будет включено в ответ, потому что include_unmapped не установлено на true для этого шаблона поля.
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "1",
"_score" : 1.0,
"_type" : "_doc",
"fields" : {
"session_data.object.some_field": [
"some_value"
]
}
}
]
}
} Пропущенные значения полей
Подробности
Раздел fields ответа возвращает только значения, которые были действительными во время индексирования. Если запрос поиска запрашивает значения из поля, которое игнорирует определённые значения из-за некорректности или из-за того, что они слишком велики, эти значения возвращаются отдельно в разделе ignored_field_values.
В этом примере мы индексируем документ, который имеет значение, которое игнорируется и не добавляется в индекс, поэтому отображается отдельно в результатах поиска:
PUT my-index-000001
{
"mappings": {
"properties": {
"my-small" : { "type" : "keyword", "ignore_above": 2 },
"my-large" : { "type" : "keyword" }
}
}
}
PUT my-index-000001/_doc/1?refresh=true
{
"my-small": ["ok", "bad"],
"my-large": "ok content"
}
POST my-index-000001/_search
{
"fields": ["my-*"],
"_source": false
} | У этого поля есть ограничение по размеру | |
| Значение поля этого документа превышает ограничение по размеру, поэтому игнорируется и не индексируется |
Ответ будет содержать пропущенные значения поля по пути ignored_field_values. Эти значения извлекаются из исходного JSON-источника документа и являются сырыми, поэтому не будут форматироваться или обрабатываться каким-либо образом, в отличие от успешно индексированных полей, которые возвращаются в разделе fields.
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_ignored" : [ "my-small"],
"fields" : {
"my-large": [
"ok content"
],
"my-small": [
"ok"
]
},
"ignored_field_values" : {
"my-small": [
"bad"
]
}
}
]
}
} Параметр _source
Вы можете использовать параметр _source для выбора, какие поля источника будут возвращены. Это называется фильтрацией источника.
В следующем запросе API поиска параметр тела запроса _source установлен на false. Источник документа не включён в ответ.
GET /_search
{
"_source": false,
"query": {
"match": {
"user.id": "kimchy"
}
}
} Чтобы вернуть только подмножество полей источника, укажите шаблон подстановки (*) в параметре _source. В следующем запросе API поиска возвращается источник только для поля obj и его свойств.
GET /_search
{
"_source": "obj.*",
"query": {
"match": {
"user.id": "kimchy"
}
}
} Вы также можете указать массив шаблонов подстановок в поле _source. В следующем запросе API поиска возвращается источник только для полей obj1 и obj2 и их свойств.
GET /_search
{
"_source": [ "obj1.*", "obj2.*" ],
"query": {
"match": {
"user.id": "kimchy"
}
}
} Для более тонкого управления вы можете указать объект, содержащий массивы шаблонов includes и excludes в параметре _source.
Если свойство includes указано, возвращаются только поля источника, соответствующие одному из его шаблонов. Вы можете исключить поля из этого подмножества, используя свойство excludes.
Если свойство includes не указано, возвращается весь исходный документ, за исключением полей, соответствующих шаблону в свойстве excludes.
Следующий запрос API поиска возвращает исходные данные только для полей obj1 и obj2 и их свойств, исключая любые дочерние поля description.
GET /_search
{
"_source": {
"includes": [ "obj1.*", "obj2.*" ],
"excludes": [ "*.description" ]
},
"query": {
"term": {
"user.id": "kimchy"
}
}
} Другие методы получения данных
Исходные данные документа _source хранятся как одно поле в Lucene. Эта структура означает, что весь объект _source должен быть загружен и проанализирован, даже если вы запрашиваете только часть из него. Чтобы избежать этого ограничения, вы можете попробовать другие варианты загрузки полей:
- Используйте параметр
docvalue_fields, чтобы получить значения для выбранных полей. Это может быть хороший выбор, когда возвращается небольшое количество полей, поддерживающих doc values, таких как ключевые слова и даты. - Используйте параметр
stored_fields, чтобы получить значения для определённых сохранённых полей (полей, использующих параметрstoreотображения).
Elasticsearch всегда пытается загрузить значения из _source. Это поведение имеет те же последствия для фильтрации источника, где Elasticsearch нужно загрузить и проанализировать весь _source, чтобы получить только одно поле.
Поля doc values
Вы можете использовать параметр docvalue_fields, чтобы вернуть значения doc values для одного или нескольких полей в ответе поиска.
Значения doc values хранят те же значения, что и _source, но в структуре на диске, основанной на столбцах, которая оптимизирована для сортировки и агрегаций. Поскольку каждое поле хранится отдельно, Elasticsearch читает только запрошенные значения полей и может избежать загрузки всего документа _source.
По умолчанию doc values хранятся для поддерживаемых полей. Однако doc values не поддерживаются для полей типа text или text_annotated.
Следующий запрос поиска использует параметр docvalue_fields для получения значений doc values для поля user.id, всех полей, начинающихся с http.response., и поля @timestamp:
GET my-index-000001/_search
{
"query": {
"match": {
"user.id": "kimchy"
}
},
"docvalue_fields": [
"user.id",
"http.response.*",
{
"field": "date",
"format": "epoch_millis"
}
]
} | Принимаются как полные имена полей, так и шаблоны с подстановкой. | |
| Используя обозначение объектов, вы можете передать параметр |
Нельзя использовать параметр docvalue_fields для получения значений doc values вложенных объектов. Если вы указываете вложенный объект, поиск возвращает пустой массив ([ ]) для поля. Для доступа к вложенным полям используйте свойство docvalue_fields параметра inner_hits.
Сохраненные поля
Также можно сохранить значения отдельных полей, используя опцию отображения store. Вы можете использовать параметр stored_fields для включения этих сохранённых значений в ответ поиска.
Параметр stored_fields предназначен для полей, явно помеченных как сохранённые в отображении, что по умолчанию отключено и обычно не рекомендуется. Используйте фильтрацию источника, чтобы выбрать подмножества исходного документа, которые нужно вернуть.
Позволяет выборочно загружать определенные сохраненные поля для каждого документа, представленного результатом поиска.
GET /_search
{
"stored_fields" : ["user", "postDate"],
"query" : {
"term" : { "user" : "kimchy" }
}
} * может быть использован для загрузки всех сохранённых полей из документа.
Пустой массив приведет к возвращению только _id и _type для каждого результата, например:
GET /_search
{
"stored_fields" : [],
"query" : {
"term" : { "user" : "kimchy" }
}
} Если запрошенные поля не сохранены (store отображение установлено в false), они будут проигнорированы.
Значения сохранённых полей, извлечённые из самого документа, всегда возвращаются в виде массива. Напротив, метаданные, такие как _routing, никогда не возвращаются в виде массива.
Также только листовые поля могут быть возвращены с помощью параметра stored_fields. Если указано поле объекта, оно будет проигнорировано.
Сам по себе параметр stored_fields не может быть использован для загрузки полей во вложенных объектах — если поле содержит вложенный объект в своём пути, то данные для этого сохранённого поля не будут возвращены. Для доступа к вложенным полям необходимо использовать stored_fields в блоке inner_hits.
Отключение сохранённых полей
Для отключения сохранённых полей (и метаданных) полностью используйте: _none_:
GET /_search
{
"stored_fields": "_none_",
"query" : {
"term" : { "user" : "kimchy" }
}
} Скриптовые поля
Вы можете использовать параметр script_fields для получения результата выполнения скрипта (на основе различных полей) для каждого результата. Например:
GET /_search
{
"query": {
"match_all": {}
},
"script_fields": {
"test1": {
"script": {
"lang": "painless",
"source": "doc['price'].value * 2"
}
},
"test2": {
"script": {
"lang": "painless",
"source": "doc['price'].value * params.factor",
"params": {
"factor": 2.0
}
}
}
}
} Скриптовые поля могут работать с полями, которые не хранятся (price в данном случае) и позволяют возвращать настраиваемые значения (значение, вычисленное скриптом).
Скриптовые поля также могут получить доступ к фактическому документу _source и извлечь определенные элементы для возврата, используя params['_source']. Вот пример:
GET /_search
{
"query": {
"match_all": {}
},
"script_fields": {
"test1": {
"script": "params['_source']['message']"
}
}
} Обратите внимание на ключевое слово _source для навигации по json-подобной модели.
Важно понимать разницу между doc['my_field'].value и params['_source']['my_field']. Первый, используя ключевое слово doc, приведет к загрузке терминов для этого поля в память (кеширование), что приведет к более быстрому выполнению, но большему потреблению памяти. Также обозначение doc[...] позволяет только простые знаковые поля (вы не можете вернуть json-объект из него) и имеет смысл только для неанализируемых или однословных полей. Однако использование doc по-прежнему является рекомендуемым способом доступа к значениям из документа, если это возможно, потому что _source должен быть загружен и проанализирован каждый раз, когда он используется. Использование _source очень медленно.
© 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/search-fields.html