索引运行时字段
运行时字段由其运行的上下文定义。例如,您可以在搜索查询的上下文中定义运行时字段,或者在索引映射的runtime 部分中定义。如果您决定为了获得更高的性能而索引运行时字段,请将完整的运行时字段定义(包括脚本)移动到索引映射的上下文中。Elasticsearch 会自动使用这些已索引的字段来驱动查询,从而实现快速响应时间。这种能力意味着您只需编写一次脚本,并将其应用于任何支持运行时字段的上下文。
目前不支持索引 composite 运行时字段。
然后,您可以使用运行时字段来限制 Elasticsearch 需要计算值的字段数量。将已索引字段与运行时字段结合使用,可以为您索引的数据以及定义其他字段查询的方式提供灵活性。
索引运行时字段后,您无法更新其中包含的脚本。如果您需要更改脚本,请使用更新后的脚本创建一个新字段。
例如,假设您的公司想要更换一些旧的压力阀。连接的传感器只能报告真实读数的一小部分。与其为压力阀配备新传感器,不如决定根据报告的读数计算数值。根据报告的数据,您在 my-index-000001 的映射中定义了以下字段
PUT my-index-000001/
{
"mappings": {
"properties": {
"timestamp": {
"type": "date"
},
"temperature": {
"type": "long"
},
"voltage": {
"type": "double"
},
"node": {
"type": "keyword"
}
}
}
}
然后,您批量索引来自传感器的一些示例数据。这些数据包括每个传感器的 voltage 读数
POST my-index-000001/_bulk?refresh=true
{"index":{}}
{"timestamp": 1516729294000, "temperature": 200, "voltage": 5.2, "node": "a"}
{"index":{}}
{"timestamp": 1516642894000, "temperature": 201, "voltage": 5.8, "node": "b"}
{"index":{}}
{"timestamp": 1516556494000, "temperature": 202, "voltage": 5.1, "node": "a"}
{"index":{}}
{"timestamp": 1516470094000, "temperature": 198, "voltage": 5.6, "node": "b"}
{"index":{}}
{"timestamp": 1516383694000, "temperature": 200, "voltage": 4.2, "node": "c"}
{"index":{}}
{"timestamp": 1516297294000, "temperature": 202, "voltage": 4.0, "node": "c"}
在与几位现场工程师交谈后,您意识到传感器报告的数值应该是当前数值的至少 double(两倍),甚至可能更高。您创建了一个名为 voltage_corrected 的运行时字段,它会检索当前电压并将其乘以 2
PUT my-index-000001/_mapping
{
"runtime": {
"voltage_corrected": {
"type": "double",
"script": {
"source": """
emit(doc['voltage'].value * params['multiplier'])
""",
"params": {
"multiplier": 2
}
}
}
}
}
您可以使用 _search API 上的 fields 参数检索计算出的值
GET my-index-000001/_search
{
"fields": [
"voltage_corrected",
"node"
],
"size": 2
}
在审查传感器数据并运行一些测试后,您确定报告的传感器数据的乘数应该是 4。为了获得更高的性能,您决定使用新的 multiplier 参数索引 voltage_corrected 运行时字段。
在一个名为 my-index-000001 的新索引中,将 voltage_corrected 运行时字段定义复制到新索引的映射中。就是这么简单!您可以添加一个名为 on_script_error 的可选参数,该参数决定了如果脚本在索引时抛出错误(默认行为),是否拒绝整个文档。
PUT my-index-000001/
{
"mappings": {
"properties": {
"timestamp": {
"type": "date"
},
"temperature": {
"type": "long"
},
"voltage": {
"type": "double"
},
"node": {
"type": "keyword"
},
"voltage_corrected": {
"type": "double",
"on_script_error": "fail",
"script": {
"source": """
emit(doc['voltage'].value * params['multiplier'])
""",
"params": {
"multiplier": 4
}
}
}
}
}
}
- 如果脚本在索引时抛出错误,则会导致整个文档被拒绝。将该值设置为
ignore将在文档的_ignored元数据字段中注册该字段,并继续索引。
将来自传感器的一些示例数据批量索引到 my-index-000001 索引中
POST my-index-000001/_bulk?refresh=true
{ "index": {}}
{ "timestamp": 1516729294000, "temperature": 200, "voltage": 5.2, "node": "a"}
{ "index": {}}
{ "timestamp": 1516642894000, "temperature": 201, "voltage": 5.8, "node": "b"}
{ "index": {}}
{ "timestamp": 1516556494000, "temperature": 202, "voltage": 5.1, "node": "a"}
{ "index": {}}
{ "timestamp": 1516470094000, "temperature": 198, "voltage": 5.6, "node": "b"}
{ "index": {}}
{ "timestamp": 1516383694000, "temperature": 200, "voltage": 4.2, "node": "c"}
{ "index": {}}
{ "timestamp": 1516297294000, "temperature": 202, "voltage": 4.0, "node": "c"}
现在,您可以在搜索查询中检索计算出的值,并根据精确的数值查找文档。以下范围查询将返回所有计算出的 voltage_corrected 大于或等于 16 且小于或等于 20 的文档。同样,使用 _search API 上的 fields 参数来检索您想要的字段
POST my-index-000001/_search
{
"query": {
"range": {
"voltage_corrected": {
"gte": 16,
"lte": 20,
"boost": 1.0
}
}
},
"fields": ["voltage_corrected", "node"]
}
响应中包含匹配范围查询的文档的 voltage_corrected 字段,该字段基于所包含脚本的计算值
{
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my-index-000001",
"_id" : "yoSLrHgBdg9xpPrUZz_P",
"_score" : 1.0,
"_source" : {
"timestamp" : 1516383694000,
"temperature" : 200,
"voltage" : 4.2,
"node" : "c"
},
"fields" : {
"voltage_corrected" : [
16.8
],
"node" : [
"c"
]
}
},
{
"_index" : "my-index-000001",
"_id" : "y4SLrHgBdg9xpPrUZz_P",
"_score" : 1.0,
"_source" : {
"timestamp" : 1516297294000,
"temperature" : 202,
"voltage" : 4.0,
"node" : "c"
},
"fields" : {
"voltage_corrected" : [
16.0
],
"node" : [
"c"
]
}
}
]
}
}