索引运行时字段
编辑索引运行时字段
编辑运行时字段由其运行的上下文定义。例如,您可以在搜索查询的上下文中或索引映射的runtime
部分中定义运行时字段。如果您决定索引运行时字段以提高性能,只需将完整的运行时字段定义(包括脚本)移动到索引映射的上下文中。Elasticsearch 会自动使用这些已索引的字段来驱动查询,从而实现快速的响应时间。此功能意味着您可以只编写一次脚本,并将其应用于任何支持运行时字段的上下文。
目前不支持索引composite
运行时字段。
然后,您可以使用运行时字段来限制 Elasticsearch 需要计算值的字段数量。将已索引的字段与运行时字段一起使用,可以灵活地索引数据以及定义其他字段的查询方式。
索引运行时字段后,您无法更新包含的脚本。如果您需要更改脚本,请使用更新后的脚本创建一个新字段。
例如,假设您的公司想要更换一些旧的压力阀。连接的传感器只能报告真实读数的一部分。与其为压力阀配备新的传感器,您决定根据报告的读数来计算值。根据报告的数据,您为my-index-000001
的映射中定义了以下字段:
resp = client.indices.create( index="my-index-000001", mappings={ "properties": { "timestamp": { "type": "date" }, "temperature": { "type": "long" }, "voltage": { "type": "double" }, "node": { "type": "keyword" } } }, ) print(resp)
response = client.indices.create( index: 'my-index-000001', body: { mappings: { properties: { timestamp: { type: 'date' }, temperature: { type: 'long' }, voltage: { type: 'double' }, node: { type: 'keyword' } } } } ) puts response
const response = await client.indices.create({ index: "my-index-000001", mappings: { properties: { timestamp: { type: "date", }, temperature: { type: "long", }, voltage: { type: "double", }, node: { type: "keyword", }, }, }, }); console.log(response);
PUT my-index-000001/ { "mappings": { "properties": { "timestamp": { "type": "date" }, "temperature": { "type": "long" }, "voltage": { "type": "double" }, "node": { "type": "keyword" } } } }
然后,您批量索引来自传感器的样本数据。此数据包括每个传感器的voltage
读数。
resp = client.bulk( index="my-index-000001", refresh=True, operations=[ { "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, "node": "c" } ], ) print(resp)
response = client.bulk( index: 'my-index-000001', refresh: true, body: [ { index: {} }, { timestamp: 1_516_729_294_000, temperature: 200, voltage: 5.2, node: 'a' }, { index: {} }, { timestamp: 1_516_642_894_000, temperature: 201, voltage: 5.8, node: 'b' }, { index: {} }, { timestamp: 1_516_556_494_000, temperature: 202, voltage: 5.1, node: 'a' }, { index: {} }, { timestamp: 1_516_470_094_000, temperature: 198, voltage: 5.6, node: 'b' }, { index: {} }, { timestamp: 1_516_383_694_000, temperature: 200, voltage: 4.2, node: 'c' }, { index: {} }, { timestamp: 1_516_297_294_000, temperature: 202, voltage: 4, node: 'c' } ] ) puts response
const response = await client.bulk({ index: "my-index-000001", refresh: "true", operations: [ { 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, node: "c", }, ], }); console.log(response);
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
的运行时字段,它检索当前电压并将其乘以2
。
resp = client.indices.put_mapping( index="my-index-000001", runtime={ "voltage_corrected": { "type": "double", "script": { "source": "\n emit(doc['voltage'].value * params['multiplier'])\n ", "params": { "multiplier": 2 } } } }, ) print(resp)
response = client.indices.put_mapping( index: 'my-index-000001', body: { runtime: { voltage_corrected: { type: 'double', script: { source: "\n emit(doc['voltage'].value * params['multiplier'])\n ", params: { multiplier: 2 } } } } } ) puts response
const response = await client.indices.putMapping({ index: "my-index-000001", runtime: { voltage_corrected: { type: "double", script: { source: "\n emit(doc['voltage'].value * params['multiplier'])\n ", params: { multiplier: 2, }, }, }, }, }); console.log(response);
PUT my-index-000001/_mapping { "runtime": { "voltage_corrected": { "type": "double", "script": { "source": """ emit(doc['voltage'].value * params['multiplier']) """, "params": { "multiplier": 2 } } } } }
您可以使用_search
API 上的fields
参数检索计算出的值。
resp = client.search( index="my-index-000001", fields=[ "voltage_corrected", "node" ], size=2, ) print(resp)
response = client.search( index: 'my-index-000001', body: { fields: [ 'voltage_corrected', 'node' ], size: 2 } ) puts response
const response = await client.search({ index: "my-index-000001", fields: ["voltage_corrected", "node"], size: 2, }); console.log(response);
GET my-index-000001/_search { "fields": [ "voltage_corrected", "node" ], "size": 2 }
在审查传感器数据并运行一些测试后,您确定报告的传感器数据的乘数应该是4
。为了获得更高的性能,您决定使用新的multiplier
参数索引voltage_corrected
运行时字段。
在新索引my-index-000001
中,将voltage_corrected
运行时字段定义复制到新索引的映射中。就这么简单!您可以添加一个名为on_script_error
的可选参数,该参数确定如果脚本在索引时抛出错误是否拒绝整个文档(默认值)。
resp = client.indices.create( index="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": "\n emit(doc['voltage'].value * params['multiplier'])\n ", "params": { "multiplier": 4 } } } } }, ) print(resp)
response = client.indices.create( index: 'my-index-000001', body: { mappings: { properties: { timestamp: { type: 'date' }, temperature: { type: 'long' }, voltage: { type: 'double' }, node: { type: 'keyword' }, voltage_corrected: { type: 'double', on_script_error: 'fail', script: { source: "\n emit(doc['voltage'].value * params['multiplier'])\n ", params: { multiplier: 4 } } } } } } ) puts response
const response = await client.indices.create({ index: "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: "\n emit(doc['voltage'].value * params['multiplier'])\n ", params: { multiplier: 4, }, }, }, }, }, }); console.log(response);
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 } } } } } }
将来自传感器的样本数据批量索引到my-index-000001
索引中。
resp = client.bulk( index="my-index-000001", refresh=True, operations=[ { "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, "node": "c" } ], ) print(resp)
response = client.bulk( index: 'my-index-000001', refresh: true, body: [ { index: {} }, { timestamp: 1_516_729_294_000, temperature: 200, voltage: 5.2, node: 'a' }, { index: {} }, { timestamp: 1_516_642_894_000, temperature: 201, voltage: 5.8, node: 'b' }, { index: {} }, { timestamp: 1_516_556_494_000, temperature: 202, voltage: 5.1, node: 'a' }, { index: {} }, { timestamp: 1_516_470_094_000, temperature: 198, voltage: 5.6, node: 'b' }, { index: {} }, { timestamp: 1_516_383_694_000, temperature: 200, voltage: 4.2, node: 'c' }, { index: {} }, { timestamp: 1_516_297_294_000, temperature: 202, voltage: 4, node: 'c' } ] ) puts response
const response = await client.bulk({ index: "my-index-000001", refresh: "true", operations: [ { 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, node: "c", }, ], }); console.log(response);
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
参数来检索所需的字段。
resp = client.search( index="my-index-000001", query={ "range": { "voltage_corrected": { "gte": 16, "lte": 20, "boost": 1 } } }, fields=[ "voltage_corrected", "node" ], ) print(resp)
const response = await client.search({ index: "my-index-000001", query: { range: { voltage_corrected: { gte: 16, lte: 20, boost: 1, }, }, }, fields: ["voltage_corrected", "node"], }); console.log(response);
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" ] } } ] } }