在查询时覆盖字段值编辑

如果创建一个与映射中已存在的字段同名的运行时字段,则运行时字段会覆盖映射的字段。在查询时,Elasticsearch 会评估运行时字段,根据脚本计算值,并将该值作为查询的一部分返回。由于运行时字段会覆盖映射的字段,因此您可以覆盖搜索中返回的值,而无需修改映射的字段。

例如,假设您将以下文档索引到 my-index-000001

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
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 匹配的文档

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match: {
        model_number: 'HG537PU'
      }
    }
  }
)
puts 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
          }
        }
      }
    ]
  }
}

以下请求定义了一个运行时字段,其中脚本评估值为 HG537PUmodel_number 字段。对于每个匹配项,脚本将 voltage 字段的值乘以 1.7

使用 fields 参数在 _search API 上,您可以检索脚本为与搜索请求匹配的文档的 measures.voltage 字段计算的值

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
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
          ]
        }
      }
    ]
  }
}