在查询时覆盖字段值

编辑

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

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

resp = client.bulk(
    index="my-index-000001",
    refresh=True,
    operations=[
        {
            "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
            }
        }
    ],
)
print(resp)
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
const response = await client.bulk({
  index: "my-index-000001",
  refresh: "true",
  operations: [
    {
      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,
      },
    },
  ],
});
console.log(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 匹配的文档

resp = client.search(
    index="my-index-000001",
    query={
        "match": {
            "model_number": "HG537PU"
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match: {
        model_number: 'HG537PU'
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  query: {
    match: {
      model_number: "HG537PU",
    },
  },
});
console.log(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
          }
        }
      }
    ]
  }
}

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

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

resp = client.search(
    index="my-index-000001",
    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"
    ],
)
print(resp)
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
const response = await client.search({
  index: "my-index-000001",
  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"],
});
console.log(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
          ]
        }
      }
    ]
  }
}