加载中

在查询时覆盖字段值

如果你创建一个与映射中已存在的字段同名的运行时字段,该运行时字段会遮蔽原有的映射字段。在查询时,Elasticsearch 会评估该运行时字段,根据脚本计算出一个值,并将该值作为查询的一部分返回。由于运行时字段遮蔽了映射字段,你可以在不修改映射字段的情况下覆盖搜索返回的值。

例如,假设你将以下文档索引到了 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
          }
        }
      }
    ]
  }
}
		

以下请求定义了一个运行时字段,其中脚本会对 model_number 值为 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.146.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
          ]
        }
      }
    ]
  }
}
		
© . This website operates independently and is not affiliated with or endorsed by Elasticsearch B.V. All brand names, logos, and trademarks are the property of their respective owners.