【官方文档翻译】映射 - 运行时字段 - Elasticsearch

106 阅读5分钟

运行时字段(Runtime fields)

一个运行时字段是一个在运行时估值的字段。运行时字段使你能够:

  • 向现有的文档添加字段不需要重新索引你的数据
  • 和你的数据一起开始工作而不需要明白它是怎样的结构
  • 覆盖掉从一个索引过的字段查询时返回的值
  • 为一个特定的用途定义字段而不需要改变底层的模式

你可以像其它字段一样从搜索API来访问运行时字段,并且 ES 看待运行时字段也没有什么不同。你可以在索引映射搜索请求里定义运行时字段。你的选择,也是运行时字段内在灵活性的一部分。
使用 _search 上的 fields 字段检索运行时字段的值。运行时字段不会在 _source 里显示,但是 fields API 为所有的字段工作,甚至那些不会作为原始 _source 的一部分被发送的字段。
运行时字段当和日志数据一起工作时是有用的(查看例子),尤其当你不确定数据结构时。你的搜索速度下降,但是索引的尺寸很小,那么不需要索引它们你也能很快地处理日志。

1. 好处

因为运行时字段是不被索引的,所以添加一个运行时字段不会增加索引的大小。你在索引映射里直接定义运行时字段,节省存储成本和提升摄取速度。你能很快的摄取数据到Elastic栈里并且能立刻访问它。当你定义了一个运行时字段,你可以立即在搜索请求、聚合、过滤和排序里使用它。
如果你使运行时字段成为一个被索引的字段,你不需要改变任何涉及到运行时字段的查询。更好的是,你可以引用一些索引,其中的字段是运行时字段,而其它索引中的字段是索引字段。你可以灵活的选择哪个字段被索引而哪个字段保持为运行时字段。
在它的核心,运行时字段最重要的好处是能够在你摄取文档之后将字段添加进去。这个能力简化了映射决定因为你不需要先决定如何解析你的数据,你可以使用运行时字段随时修正你的映射。

2. 动机

运行时字段可以替换掉你能使用带有 _search API 的脚本的很多种情况。如何使用一个运行时字段受到被包含的脚本在其上运行的文档的数量的影响。例如,如果你使用在 _search API 上的 fields 参数检索运行时字段的值,脚本只会针对顶层的命中就像脚本字段做的那样。
你能使用脚本字段访问 _source 里的值并且返回基于脚本估算的计算值。运行时字段有相同的能力,但是提供了更大的灵活性,因为你能在一个搜索请求里在运行时字段上查询和聚合。脚本字段只能抓取值。
相似地,你可以基于脚本写一个脚本查询在一个搜索请求里过滤文档。运行时字段提供了一个相似的特性但是更灵活。你写一个脚本创建了字段值然后它们可在任何地方获得,比如 fields所有查询,和 聚合
你也可以使用脚本排序搜索结果,但是相同的脚本实际上和在一个运行时字段里工作是一样的。
如果你移动一个脚本从一个搜索请求的任何一个部分到从相同数量的文档计算值的运行时字段,性能应该差不多相同。这些特性的性能极大的依赖于包含的脚本运行的计算和有多少文档脚本在其中运行。

3. 折衷

运行时字段使用更少的空间,在如何访问你的数据上提供灵活性,但是会影响基于定义在运行时脚本里的计算的搜索性能。
要平衡搜索性能和灵活性,索引那些你频繁搜索和过滤的字段,比如一个时间戳。当运行一个查询时 ES 自动优先使用这些索引的字段,导致一个很快的响应时间。然后你可以使用运行时字段来减少 ES 需要进行计算值的字段的数量。使用索引字段串联运行时字段在你索引的数据上和如何定义其它字段的查询上提供灵活性。
使用异步搜索API运行包含运行时字段的搜索。这个搜索方法可以帮助你弥补在包含运行时字段的每一个文档里对字段值进行计算的性能影响。如果查询不能同步地返回结果集,你将在它们变得可获得的时候异步的得到结果。

在运行时字段上的查询被认为时昂贵的。如果 search.allow_expensive_queries被设置为 false,昂贵的查询不再被允许并且 ES 将拒绝任何针对运行时字段的查询。