在查询时覆盖字段值
如果你创建了一个和现有的映射里的字段同名的运行时字段,此运行时字段会影射到映射的字段。在查询时,ES估算运行时字段,基于脚本计算出一个值,将值作为查询的一部分返回。因为运行时字段是映射字段的影射,你可以覆盖搜索返回的值而不需要改变映射字段。
例如:假如你索引了下面的文档到 my-index-000001 :
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倍!你可以在 _search 请求的 runtime_mappings 部分定义一个脚本来影射 voltage 字段并在查询时计算一个新的值。
如果你搜索模型号匹配 HG537PU 的文档:
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
}
}
}
]
}
}
下面的请求定义了一个运行时字段,其中的脚本计算型号字段的值为 HG537PU 的值。 每一次匹配,脚本对 voltage 字段的值乘以 1.7。
使用 _search API上的 fields参数,为搜索请求匹配到的文档,你可以检索脚本为 measures.voltage 字段计算出的值:
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。这才对嘛!运行时字段计算出的这个值作为搜索请求的一部分,而且不会改变映射的值,它们仍然在响应里返回:
{
...
"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
]
}
}
]
}
}