Переопределение значений поля во время запроса
Если вы создаёте поле runtime с тем же именем, что и поле, уже существующее в схеме, поле runtime затеневает поле схемы. Во время запроса Elasticsearch вычисляет поле runtime, рассчитывает значение на основе скрипта и возвращает значение в рамках запроса. Поскольку поле runtime затеневает поле схемы, вы можете переопределить возвращаемое значение в поиске, не изменяя поле схемы.
Например, давайте предположим, что вы индексировали следующие документы в my-index-000001:
resp = client.bulk(
index="my-index-000001",
refresh=True,
operations=[
{
"index": {}
},
{
"@timestamp": 1516729294000,
"model_number": "QVKC92Q",
"measures": {
"voltage": 5.2
}
},
{
"index": {}
},
{
"@timestamp": 1516642894000,
"model_number": "QVKC92Q",
"measures": {
"voltage": 5.8
}
},
{
"index": {}
},
{
"@timestamp": 1516556494000,
"model_number": "QVKC92Q",
"measures": {
"voltage": 5.1
}
},
{
"index": {}
},
{
"@timestamp": 1516470094000,
"model_number": "QVKC92Q",
"measures": {
"voltage": 5.6
}
},
{
"index": {}
},
{
"@timestamp": 1516383694000,
"model_number": "HG537PU",
"measures": {
"voltage": 4.2
}
},
{
"index": {}
},
{
"@timestamp": 1516297294000,
"model_number": "HG537PU",
"measures": {
"voltage": 4
}
}
],
)
print(resp) response = client.bulk(
index: 'my-index-000001',
refresh: true,
body: [
{
index: {}
},
{
"@timestamp": 1_516_729_294_000,
model_number: 'QVKC92Q',
measures: {
voltage: 5.2
}
},
{
index: {}
},
{
"@timestamp": 1_516_642_894_000,
model_number: 'QVKC92Q',
measures: {
voltage: 5.8
}
},
{
index: {}
},
{
"@timestamp": 1_516_556_494_000,
model_number: 'QVKC92Q',
measures: {
voltage: 5.1
}
},
{
index: {}
},
{
"@timestamp": 1_516_470_094_000,
model_number: 'QVKC92Q',
measures: {
voltage: 5.6
}
},
{
index: {}
},
{
"@timestamp": 1_516_383_694_000,
model_number: 'HG537PU',
measures: {
voltage: 4.2
}
},
{
index: {}
},
{
"@timestamp": 1_516_297_294_000,
model_number: 'HG537PU',
measures: {
voltage: 4
}
}
]
)
puts response const response = await client.bulk({
index: "my-index-000001",
refresh: "true",
operations: [
{
index: {},
},
{
"@timestamp": 1516729294000,
model_number: "QVKC92Q",
measures: {
voltage: 5.2,
},
},
{
index: {},
},
{
"@timestamp": 1516642894000,
model_number: "QVKC92Q",
measures: {
voltage: 5.8,
},
},
{
index: {},
},
{
"@timestamp": 1516556494000,
model_number: "QVKC92Q",
measures: {
voltage: 5.1,
},
},
{
index: {},
},
{
"@timestamp": 1516470094000,
model_number: "QVKC92Q",
measures: {
voltage: 5.6,
},
},
{
index: {},
},
{
"@timestamp": 1516383694000,
model_number: "HG537PU",
measures: {
voltage: 4.2,
},
},
{
index: {},
},
{
"@timestamp": 1516297294000,
model_number: "HG537PU",
measures: {
voltage: 4,
},
},
],
});
console.log(response); POST my-index-000001/_bulk?refresh=true
{"index":{}}
{"@timestamp":1516729294000,"model_number":"QVKC92Q","measures":{"voltage":5.2}}
{"index":{}}
{"@timestamp":1516642894000,"model_number":"QVKC92Q","measures":{"voltage":5.8}}
{"index":{}}
{"@timestamp":1516556494000,"model_number":"QVKC92Q","measures":{"voltage":5.1}}
{"index":{}}
{"@timestamp":1516470094000,"model_number":"QVKC92Q","measures":{"voltage":5.6}}
{"index":{}}
{"@timestamp":1516383694000,"model_number":"HG537PU","measures":{"voltage":4.2}}
{"index":{}}
{"@timestamp":1516297294000,"model_number":"HG537PU","measures":{"voltage":4.0}} Позже вы понимаете, что датчики HG537PU не сообщают истинное напряжение. Индексированные значения должны быть в 1,7 раза выше, чем значения, сообщённые датчиками! Вместо переиндексации данных вы можете определить скрипт в разделе runtime_mappings запроса _search для затенения поля voltage и рассчитать новое значение во время запроса.
Если вы ищете документы, где номер модели соответствует HG537PU:
resp = client.search(
index="my-index-000001",
query={
"match": {
"model_number": "HG537PU"
}
},
)
print(resp) response = client.search(
index: 'my-index-000001',
body: {
query: {
match: {
model_number: 'HG537PU'
}
}
}
)
puts response const response = await client.search({
index: "my-index-000001",
query: {
match: {
model_number: "HG537PU",
},
},
});
console.log(response); GET my-index-000001/_search
{
"query": {
"match": {
"model_number": "HG537PU"
}
}
} Ответ включает индексированные значения для документов, соответствующих номеру модели HG537PU:
{
...
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0296195,
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "F1BeSXYBg_szTodcYCmk",
"_score" : 1.0296195,
"_source" : {
"@timestamp" : 1516383694000,
"model_number" : "HG537PU",
"measures" : {
"voltage" : 4.2
}
}
},
{
"_index" : "my-index-000001",
"_id" : "l02aSXYBkpNf6QRDO62Q",
"_score" : 1.0296195,
"_source" : {
"@timestamp" : 1516297294000,
"model_number" : "HG537PU",
"measures" : {
"voltage" : 4.0
}
}
}
]
}
} Следующий запрос определяет поле runtime, где скрипт вычисляет значение поля model_number, где значение равно HG537PU. Для каждой совпавшей записи скрипт умножает значение поля voltage на 1.7.
Используя параметр fields в запросе к API _search, вы можете получить значение, вычисленное скриптом для поля measures.voltage для документов, соответствующих запросу поиска:
resp = client.search(
index="my-index-000001",
runtime_mappings={
"measures.voltage": {
"type": "double",
"script": {
"source": "if (doc['model_number.keyword'].value.equals('HG537PU'))\n {emit(1.7 * params._source['measures']['voltage']);}\n else{emit(params._source['measures']['voltage']);}"
}
}
},
query={
"match": {
"model_number": "HG537PU"
}
},
fields=[
"measures.voltage"
],
)
print(resp) response = client.search(
index: 'my-index-000001',
body: {
runtime_mappings: {
'measures.voltage' => {
type: 'double',
script: {
source: "if (doc['model_number.keyword'].value.equals('HG537PU'))\n {emit(1.7 * params._source['measures']['voltage']);}\n else{emit(params._source['measures']['voltage']);}"
}
}
},
query: {
match: {
model_number: 'HG537PU'
}
},
fields: [
'measures.voltage'
]
}
)
puts response const response = await client.search({
index: "my-index-000001",
runtime_mappings: {
"measures.voltage": {
type: "double",
script: {
source:
"if (doc['model_number.keyword'].value.equals('HG537PU'))\n {emit(1.7 * params._source['measures']['voltage']);}\n else{emit(params._source['measures']['voltage']);}",
},
},
},
query: {
match: {
model_number: "HG537PU",
},
},
fields: ["measures.voltage"],
});
console.log(response); POST my-index-000001/_search
{
"runtime_mappings": {
"measures.voltage": {
"type": "double",
"script": {
"source":
"""if (doc['model_number.keyword'].value.equals('HG537PU'))
{emit(1.7 * params._source['measures']['voltage']);}
else{emit(params._source['measures']['voltage']);}"""
}
}
},
"query": {
"match": {
"model_number": "HG537PU"
}
},
"fields": ["measures.voltage"]
} Глядя на ответ, вычисленные значения для measures.voltage для каждого результата равны 7.14 и 6.8. Вот это да! Поле runtime вычислило это значение в рамках запроса поиска, не изменяя сохранённое значение, которое по-прежнему возвращается в ответе:
{
...
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0296195,
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "F1BeSXYBg_szTodcYCmk",
"_score" : 1.0296195,
"_source" : {
"@timestamp" : 1516383694000,
"model_number" : "HG537PU",
"measures" : {
"voltage" : 4.2
}
},
"fields" : {
"measures.voltage" : [
7.14
]
}
},
{
"_index" : "my-index-000001",
"_id" : "l02aSXYBkpNf6QRDO62Q",
"_score" : 1.0296195,
"_source" : {
"@timestamp" : 1516297294000,
"model_number" : "HG537PU",
"measures" : {
"voltage" : 4.0
}
},
"fields" : {
"measures.voltage" : [
6.8
]
}
}
]
}
}
© 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/8.17/runtime-override-values.html