跳到主要内容

运行时字段

运行时字段(runtime field)是在查询时计算的字段。运行时字段使你能够:

  • 无需重新索引数据即可向现有文档添加字段
  • 在不了解数据结构的情况下开始处理数据
  • 在查询时覆盖从索引字段返回的值
  • 为特定用途定义字段,而无需修改底层 schema

你可以像访问其他字段一样通过搜索 API 访问运行时字段,Elasticsearch 对运行时字段一视同仁。你可以在索引映射或搜索请求中定义运行时字段。如何选择取决于你,这也是运行时字段与生俱来的灵活性的一部分。

使用 _search API 上的 fields 参数来检索运行时字段的值。运行时字段不会显示在 _source 中,但 fields API 对所有字段都有效,即使是那些未作为原始 _source 一部分发送的字段。

运行时字段在处理日志数据时非常有用(参阅示例),尤其是当你不确定数据结构时。你的搜索速度会下降,但索引体积会小得多,并且你无需索引日志就能更快地处理它们。

优势​

由于运行时字段不被索引,添加运行时字段不会增加索引体积。你直接在索引映射中定义运行时字段,从而节省存储成本并提高摄取速度。你可以更快地将数据摄取到 Elastic Stack 中并立即访问。定义运行时字段后,你可以立即在搜索请求、聚合、过滤和排序中使用它。

如果你将运行时字段更改为索引字段,则无需修改任何引用该运行时字段的查询。更妙的是,你可以让某些索引中该字段是运行时字段,而在另一些索引中是索引字段。你可以灵活选择哪些字段需要索引,哪些保留为运行时字段。

从根本上说,运行时字段最重要的优势在于能够在摄取文档之后向文档添加字段。这一能力简化了映射决策,因为你不必预先决定如何解析数据,并且可以随时使用运行时字段来修正映射。使用运行时字段可以获得更小的索引和更快的摄取速度,两者结合可以减少资源占用并降低运营成本。

动机​

运行时字段可以取代你在 _search API 中使用脚本的许多场景。运行时字段的使用方式会受到脚本针对的文档数量的影响。例如,如果你使用 _search API 上的 fields 参数来检索运行时字段的值,那么脚本只会针对排名靠前的命中结果运行,就像脚本字段一样。

你可以使用脚本字段访问 _source 中的值,并根据脚本计算返回计算后的值。运行时字段具有相同的能力,但提供了更大的灵活性,因为你可以在搜索请求中对运行时字段进行查询和聚合。脚本字段只能获取值。

类似地,你可以编写一个脚本查询,基于脚本在搜索请求中过滤文档。运行时字段提供了一个非常相似但更灵活的功能。你编写一个脚本来创建字段值,这些值在任何地方都可用,例如 fields、所有查询和聚合中。

你还可以使用脚本对搜索结果进行排序,而同样的脚本在运行时字段中的工作方式完全相同。

如果将脚本从搜索请求的上述任一位置移动到一个针对相同数量文档计算值的运行时字段中,性能应该大致相同。这些特性的性能在很大程度上取决于脚本所执行的计算,以及脚本针对多少文档运行。

权衡​

运行时字段占用的磁盘空间更少,并且在访问数据的方式上提供了灵活性,但可能会根据运行时脚本中定义的计算影响搜索性能。

为了平衡搜索性能与灵活性,请将经常搜索和过滤的字段(如时间戳)进行索引。Elasticsearch 在运行查询时会自动优先使用这些索引字段,从而获得更快的响应时间。然后你可以使用运行时字段来限制 Elasticsearch 需要为其计算值的字段数量。将索引字段与运行时字段结合使用,可以为你索引哪些数据以及如何为其他字段定义查询提供灵活性。

使用异步搜索 API 运行包含运行时字段的搜索。这种搜索方式有助于抵消在包含该字段的每个文档中计算运行时字段值所带来的性能影响。如果查询无法同步返回结果集,你将在结果可用时异步获得结果。

针对运行时字段的查询被视为昂贵查询。如果 search.allow_expensive_queries 设置为 false,则不允许昂贵查询,Elasticsearch 将拒绝任何针对运行时字段的查询。

原文链接