在搜索请求中定义运行时字段

编辑

在搜索请求中定义运行时字段

编辑

您可以在搜索请求中指定 runtime_mappings 部分,以创建仅作为查询一部分存在的运行时字段。 您可以像 向映射添加运行时字段 一样,在 runtime_mappings 部分中指定脚本。

在搜索请求中定义运行时字段使用与在索引映射中定义运行时字段相同的格式。只需将字段定义从索引映射中的 runtime 复制到搜索请求的 runtime_mappings 部分即可。

以下搜索请求向 runtime_mappings 部分添加了一个 day_of_week 字段。 该字段值将动态计算,并且仅在此搜索请求的上下文中有效。

resp = client.search(
    index="my-index-000001",
    runtime_mappings={
        "day_of_week": {
            "type": "keyword",
            "script": {
                "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
            }
        }
    },
    aggs={
        "day_of_week": {
            "terms": {
                "field": "day_of_week"
            }
        }
    },
)
print(resp)
const response = await client.search({
  index: "my-index-000001",
  runtime_mappings: {
    day_of_week: {
      type: "keyword",
      script: {
        source:
          "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))",
      },
    },
  },
  aggs: {
    day_of_week: {
      terms: {
        field: "day_of_week",
      },
    },
  },
});
console.log(response);
GET my-index-000001/_search
{
  "runtime_mappings": {
    "day_of_week": {
      "type": "keyword",
      "script": {
        "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
      }
    }
  },
  "aggs": {
    "day_of_week": {
      "terms": {
        "field": "day_of_week"
      }
    }
  }
}

创建使用其他运行时字段的运行时字段

编辑

您甚至可以在搜索请求中定义运行时字段,这些运行时字段从其他运行时字段返回值。例如,假设您批量索引一些传感器数据。

resp = client.bulk(
    index="my-index-000001",
    refresh=True,
    operations=[
        {
            "index": {}
        },
        {
            "@timestamp": 1516729294000,
            "model_number": "QVKC92Q",
            "measures": {
                "voltage": "5.2",
                "start": "300",
                "end": "8675309"
            }
        },
        {
            "index": {}
        },
        {
            "@timestamp": 1516642894000,
            "model_number": "QVKC92Q",
            "measures": {
                "voltage": "5.8",
                "start": "300",
                "end": "8675309"
            }
        },
        {
            "index": {}
        },
        {
            "@timestamp": 1516556494000,
            "model_number": "QVKC92Q",
            "measures": {
                "voltage": "5.1",
                "start": "300",
                "end": "8675309"
            }
        },
        {
            "index": {}
        },
        {
            "@timestamp": 1516470094000,
            "model_number": "QVKC92Q",
            "measures": {
                "voltage": "5.6",
                "start": "300",
                "end": "8675309"
            }
        },
        {
            "index": {}
        },
        {
            "@timestamp": 1516383694000,
            "model_number": "HG537PU",
            "measures": {
                "voltage": "4.2",
                "start": "400",
                "end": "8625309"
            }
        },
        {
            "index": {}
        },
        {
            "@timestamp": 1516297294000,
            "model_number": "HG537PU",
            "measures": {
                "voltage": "4.0",
                "start": "400",
                "end": "8625309"
            }
        }
    ],
)
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',
        start: '300',
        end: '8675309'
      }
    },
    {
      index: {}
    },
    {
      "@timestamp": 1_516_642_894_000,
      model_number: 'QVKC92Q',
      measures: {
        voltage: '5.8',
        start: '300',
        end: '8675309'
      }
    },
    {
      index: {}
    },
    {
      "@timestamp": 1_516_556_494_000,
      model_number: 'QVKC92Q',
      measures: {
        voltage: '5.1',
        start: '300',
        end: '8675309'
      }
    },
    {
      index: {}
    },
    {
      "@timestamp": 1_516_470_094_000,
      model_number: 'QVKC92Q',
      measures: {
        voltage: '5.6',
        start: '300',
        end: '8675309'
      }
    },
    {
      index: {}
    },
    {
      "@timestamp": 1_516_383_694_000,
      model_number: 'HG537PU',
      measures: {
        voltage: '4.2',
        start: '400',
        end: '8625309'
      }
    },
    {
      index: {}
    },
    {
      "@timestamp": 1_516_297_294_000,
      model_number: 'HG537PU',
      measures: {
        voltage: '4.0',
        start: '400',
        end: '8625309'
      }
    }
  ]
)
puts response
const response = await client.bulk({
  index: "my-index-000001",
  refresh: "true",
  operations: [
    {
      index: {},
    },
    {
      "@timestamp": 1516729294000,
      model_number: "QVKC92Q",
      measures: {
        voltage: "5.2",
        start: "300",
        end: "8675309",
      },
    },
    {
      index: {},
    },
    {
      "@timestamp": 1516642894000,
      model_number: "QVKC92Q",
      measures: {
        voltage: "5.8",
        start: "300",
        end: "8675309",
      },
    },
    {
      index: {},
    },
    {
      "@timestamp": 1516556494000,
      model_number: "QVKC92Q",
      measures: {
        voltage: "5.1",
        start: "300",
        end: "8675309",
      },
    },
    {
      index: {},
    },
    {
      "@timestamp": 1516470094000,
      model_number: "QVKC92Q",
      measures: {
        voltage: "5.6",
        start: "300",
        end: "8675309",
      },
    },
    {
      index: {},
    },
    {
      "@timestamp": 1516383694000,
      model_number: "HG537PU",
      measures: {
        voltage: "4.2",
        start: "400",
        end: "8625309",
      },
    },
    {
      index: {},
    },
    {
      "@timestamp": 1516297294000,
      model_number: "HG537PU",
      measures: {
        voltage: "4.0",
        start: "400",
        end: "8625309",
      },
    },
  ],
});
console.log(response);
POST my-index-000001/_bulk?refresh=true
{"index":{}}
{"@timestamp":1516729294000,"model_number":"QVKC92Q","measures":{"voltage":"5.2","start": "300","end":"8675309"}}
{"index":{}}
{"@timestamp":1516642894000,"model_number":"QVKC92Q","measures":{"voltage":"5.8","start": "300","end":"8675309"}}
{"index":{}}
{"@timestamp":1516556494000,"model_number":"QVKC92Q","measures":{"voltage":"5.1","start": "300","end":"8675309"}}
{"index":{}}
{"@timestamp":1516470094000,"model_number":"QVKC92Q","measures":{"voltage":"5.6","start": "300","end":"8675309"}}
{"index":{}}
{"@timestamp":1516383694000,"model_number":"HG537PU","measures":{"voltage":"4.2","start": "400","end":"8625309"}}
{"index":{}}
{"@timestamp":1516297294000,"model_number":"HG537PU","measures":{"voltage":"4.0","start": "400","end":"8625309"}}

您在索引后意识到您的数字数据被映射为 text 类型。您想对 measures.startmeasures.end 字段进行聚合,但是由于无法对 text 类型的字段进行聚合,聚合失败了。 运行时字段来解救!您可以添加与索引字段同名的运行时字段,并修改数据类型。

resp = client.indices.put_mapping(
    index="my-index-000001",
    runtime={
        "measures.start": {
            "type": "long"
        },
        "measures.end": {
            "type": "long"
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    runtime: {
      'measures.start' => {
        type: 'long'
      },
      'measures.end' => {
        type: 'long'
      }
    }
  }
)
puts response
const response = await client.indices.putMapping({
  index: "my-index-000001",
  runtime: {
    "measures.start": {
      type: "long",
    },
    "measures.end": {
      type: "long",
    },
  },
});
console.log(response);
PUT my-index-000001/_mapping
{
  "runtime": {
    "measures.start": {
      "type": "long"
    },
    "measures.end": {
      "type": "long"
    }
  }
}

运行时字段优先于索引映射中定义的同名字段。这种灵活性使您可以在不修改字段本身的情况下,覆盖现有字段并计算不同的值。如果您在索引映射中犯了错误,可以使用运行时字段来计算 覆盖 搜索请求期间映射中的值。

现在,您可以轻松地在 measures.startmeasures.end 字段上运行 平均值聚合

resp = client.search(
    index="my-index-000001",
    aggs={
        "avg_start": {
            "avg": {
                "field": "measures.start"
            }
        },
        "avg_end": {
            "avg": {
                "field": "measures.end"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    aggregations: {
      avg_start: {
        avg: {
          field: 'measures.start'
        }
      },
      avg_end: {
        avg: {
          field: 'measures.end'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  aggs: {
    avg_start: {
      avg: {
        field: "measures.start",
      },
    },
    avg_end: {
      avg: {
        field: "measures.end",
      },
    },
  },
});
console.log(response);
GET my-index-000001/_search
{
  "aggs": {
    "avg_start": {
      "avg": {
        "field": "measures.start"
      }
    },
    "avg_end": {
      "avg": {
        "field": "measures.end"
      }
    }
  }
}

响应包含聚合结果,而不会更改底层数据的值。

{
  "aggregations" : {
    "avg_start" : {
      "value" : 333.3333333333333
    },
    "avg_end" : {
      "value" : 8658642.333333334
    }
  }
}

此外,您可以定义一个运行时字段作为搜索查询的一部分来计算值,然后在同一查询中在该字段上运行 统计聚合

duration 运行时字段在索引映射中不存在,但是我们仍然可以在该字段上进行搜索和聚合。以下查询返回 duration 字段的计算值,并运行统计聚合以计算从聚合文档中提取的数字值的统计信息。

resp = client.search(
    index="my-index-000001",
    runtime_mappings={
        "duration": {
            "type": "long",
            "script": {
                "source": "\n          emit(doc['measures.end'].value - doc['measures.start'].value);\n          "
            }
        }
    },
    aggs={
        "duration_stats": {
            "stats": {
                "field": "duration"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    runtime_mappings: {
      duration: {
        type: 'long',
        script: {
          source: "\n          emit(doc['measures.end'].value - doc['measures.start'].value);\n          "
        }
      }
    },
    aggregations: {
      duration_stats: {
        stats: {
          field: 'duration'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  runtime_mappings: {
    duration: {
      type: "long",
      script: {
        source:
          "\n          emit(doc['measures.end'].value - doc['measures.start'].value);\n          ",
      },
    },
  },
  aggs: {
    duration_stats: {
      stats: {
        field: "duration",
      },
    },
  },
});
console.log(response);
GET my-index-000001/_search
{
  "runtime_mappings": {
    "duration": {
      "type": "long",
      "script": {
        "source": """
          emit(doc['measures.end'].value - doc['measures.start'].value);
          """
      }
    }
  },
  "aggs": {
    "duration_stats": {
      "stats": {
        "field": "duration"
      }
    }
  }
}

即使 duration 运行时字段仅在搜索查询的上下文中存在,您也可以在该字段上进行搜索和聚合。这种灵活性非常强大,使您可以在单个搜索请求中纠正索引映射中的错误并动态完成计算。

{
  "aggregations" : {
    "duration_stats" : {
      "count" : 6,
      "min" : 8624909.0,
      "max" : 8675009.0,
      "avg" : 8658309.0,
      "sum" : 5.1949854E7
    }
  }
}