Elasticsearch:Runtime fields - 运行时字段(一)

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

  • 向现有文档添加字段而无需重新索引数据
  • 开始处理数据而无需了解其结构
  • 在查询时覆盖索引字段返回的值
  • 定义用于特定用途的字段而无需修改底层架构

你可以像访问其他任何字段一样从 search API 访问运行时字段,Elasticsearch 对运行时字段的看法也一样。你可以在 index mapping 或 search request 中定义运行时字段。你的选择是运行时字段固有灵活性的一部分。

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

运行时字段在处理日志数据时很有用(参见后面的示例),尤其是当你不确定数据结构时。你的搜索速度会降低,但索引大小会小得多,你可以更快地处理日志而无需索引它们。

使用运行时字段带来的好处

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

如果将运行时字段更改为索引字段,则无需修改引用该运行时字段的任何查询。更好的是,你可以引用一些字段是运行时字段的索引,以及字段是索引字段(indexed field)的其他索引。你可以灵活地选择要索引哪些字段以及将哪些字段保留为运行时字段。

从本质上讲,运行时字段最重要的好处是能够在提取字段后将字段添加到文档中。此功能简化了映射决策,因为你不必预先决定如何解析数据,并且可以随时使用运行时字段来修改映射。使用运行时字段允许更小的索引和更快的摄取时间,从而结合使用更少的资源并降低运营成本。

激励

运行时字段可以取代使用 _search API 编写脚本的许多方式。运行时字段的使用方式受所包含脚本所针对的文档数量的影响。例如,如果你使用 _search API 上的 fields 参数来检索运行时字段的值,则脚本只会像脚本字段一样针对热门匹配项运行。

你可以使用脚本字段(script fields)访问 _source 中的值并返回基于脚本估值的计算值。运行时字段具有相同的功能,但提供了更大的灵活性,因为你可以在搜索请求中查询和聚合运行时字段。脚本字段只能获取值。

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

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

如果你将脚本从搜索请求中的任何部分移至从相同数量的文档计算值的运行时字段,则性能应该大致相同。这些功能的性能在很大程度上取决于所包含脚本正在运行的计算以及脚本针对多少个文档运行。

折衷

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

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

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

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

映射运行时字段

通过在映射定义下添加运行时部分并定义 Painless 脚本,可以映射运行时字段。此脚本可以访问文档的整个上下文,包括通过 params._source 访问的原始 _source 以及任何映射字段及其值。在查询时,脚本会运行并为查询所需的每个脚本字段生成值。

发出运行时字段值

在定义用于运行时字段的 Painless 脚本时,必须包含 emit 方法来发出计算值。

例如,以下请求中的脚本从 @timestamp 字段(定义为日期类型)计算星期几。该脚本根据 timestamp 的值计算星期几,并使用 emit 返回计算值。

PUT my-index-000001
{"mappings": {"runtime": {"day_of_week": {"type": "keyword","script": {"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"}}},"properties": {"@timestamp": {"type": "date"}}}
}PUT my-index-000001/_doc/1
{"@timestamp": "2024-06-24T04:54:59"
}

我们可以使用如下的命令来查看我们的索引:

GET my-index-000001/_search
{"fields": ["day_of_week"]
}

上面的命令返回的结果为:

{"took": 19,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 1,"hits": [{"_index": "my-index-000001","_id": "1","_score": 1,"_source": {"@timestamp": "2024-06-24T04:54:59"},"fields": {"day_of_week": ["Monday"]}}]}
}

在上面,我们可以看到 day_of_week 的字段值为 Monday。

runtime 部分可以是以下任何一种数据类型:

  • boolean
  • composite
  • date
  • double
  • geo_point
  • ip
  • keyword
  • long
  • lookup

具有日期类型的运行时字段可以接受与 date 字段类型完全相同的 format 参数。

具有 lookup 类型的运行时字段允许从相关索引中检索字段。请详细参阅之后的章节。如果启用了 dynamic field mapping,其中 dynamic 参数设置为 runtime,则新字段将自动作为运行时字段添加到索引映射中:

PUT my-index-000001
{"mappings": {"dynamic": "runtime","properties": {"@timestamp": {"type": "date"}}}
}

定义运行时字段而不使用脚本

运行时字段通常包含一个 Painless 脚本,该脚本以某种方式操纵数据。但是,有些情况下,你可能会定义一个运行时字段而不使用脚本。例如,如果你想从 _source 中检索单个字段而不进行更改,则不需要脚本。你可以创建一个没有脚本的运行时字段,例如 day_of_week:

PUT my-index-000001/
{"mappings": {"runtime": {"day_of_week": {"type": "keyword"}}}
}

如果未提供脚本,Elasticsearch 会在查询时隐式地在 _source 中查找与运行时字段同名的字段,并返回一个值(如果存在)。如果不存在同名的字段,则响应不包含该运行时字段的任何值。

在大多数情况下,尽可能通过 doc_values 检索字段值。由于数据从 Lucene 加载的方式,使用运行时字段访问 doc_values 比从 _source 检索值更快。

但是,在某些情况下,从 _source 检索字段是必要的。例如,文本字段默认没有可用的 doc_values,因此你必须从 _source 检索值。在其他情况下,你可以选择在特定字段上禁用 doc_values。

注意:你也可以在要检索值的字段前加上 params._source 前缀(例如 params._source.day_of_week)。为简单起见,建议尽可能在映射定义中定义运行时字段而不使用脚本。

忽略运行时字段上的脚本错误

脚本可能会在运行时抛出错误,例如访问文档中缺失或无效的值或执行无效操作时。当发生这种情况时,on_script_error 参数可用于控制错误行为。将此参数设置为 continue 将默认忽略此运行时字段上的所有错误。默认失败值将导致分片失败,并在搜索响应中报告。

更新和删除运行时字段

你可以随时更新或删除运行时字段。要替换现有运行时字段,请将新运行时字段添加到同名映射中。要从映射中删除运行时字段,请将运行时字段的值设置为 null:

PUT my-index-000001/_mapping
{"runtime": {"day_of_week": null}
}

下游影响 - Downstream impacts

在依赖查询运行时更新或删除运行时字段可能会返回不一致的结果。每个分片可能有权访问脚本的不同版本,具体取决于映射更改的生效时间。

警告:如果你删除或更新字段,则 Kibana 中依赖于运行时字段的现有查询或可视化可能会失败。例如,如果将类型更改为布尔值或删除运行时字段,则使用 ip 类型运行时字段的条形图可视化将会失败。

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

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

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

以下搜索请求将 day_of_week 字段添加到 runtime_mappings 部分。字段值将动态计算,并且仅在此搜索请求的上下文中计算:

DELETE my-index-000001PUT my-index-000001/_doc/1
{"@timestamp": "2024-06-24T04:54:59"
}GET my-index-000001/_search
{"runtime_mappings": {"day_of_week": {"type": "keyword","script": {"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"}}},"aggs": {"day_of_week": {"terms": {"field": "day_of_week"}}}
}

上面查询请求的结果为:

{"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 1,"hits": [{"_index": "my-index-000001","_id": "1","_score": 1,"_source": {"@timestamp": "2024-06-24T04:54:59"}}]},"aggregations": {"day_of_week": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "Monday","doc_count": 1}]}}
}

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

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

DELETE my-index-000001POST 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.start 和 measures.end 字段上进行聚合,但聚合失败,因为你无法在文本类型的字段上进行聚合。运行时字段来拯救你!你可以添加与索引字段同名的运行时字段并修改数据类型:

PUT my-index-000001/_mapping
{"runtime": {"measures.start": {"type": "long"},"measures.end": {"type": "long"}}
}

运行时字段优先于索引映射中用相同名称定义的字段。这种灵活性允许你隐藏现有字段并计算不同的值,而无需修改字段本身。如果你在索引映射中犯了错误,则可以使用运行时字段来计算在搜索请求期间覆盖映射中的值的值。

现在,你可以轻松地对 measures.start 和 measures.end 字段运行平均聚合:

GET my-index-000001/_search
{"size": 0, "aggs": {"avg_start": {"avg": {"field": "measures.start"}},"avg_end": {"avg": {"field": "measures.end"}}}
}

响应包括聚合结果,但不改变基础数据的值:

此外,你可以将运行时字段定义为计算值的搜索查询的一部分,然后在同一查询中对该字段运行统计聚合。

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

GET my-index-000001/_search
{"size": 0, "runtime_mappings": {"duration": {"type": "long","script": {"source": """emit(doc['measures.end'].value - doc['measures.start'].value);"""}}},"aggs": {"duration_stats": {"stats": {"field": "duration"}}}
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864870.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bash条件判断基础adsawq1`1nn

判断的作用 判断后续操作的提前条件是否满足如果满足执行一种命令不满足则执行另一种指令 条件测试类型: 整型测试字符测试文字测试 整数测试:比较两个整数谁大谁小,是否相等; 二元测试: num1 操作符 num2 -eq: 等于…

uniapp封装虚拟列表滚动组件

uniapp封装虚拟列表滚动组件 这里用到一个列表&#xff0c;然后数据可能有很多很多…&#xff0c;一次性全部渲染到dom上会卡顿&#xff0c;很废性能&#xff0c;于是用了这个虚拟列表就变丝滑很多很多。 组件mosoweInventedList 代码&#xff1a; <!-- 虚拟滚动列表组件&a…

代码随想录Day67(图论 part04)

110.字符串接龙 题目&#xff1a;110. 字符串接龙 (kamacoder.com) 思路&#xff1a;没有思路 答案 import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();String beginStr sc…

华为手机怎么打印文件?

关于华为手机打印的问题&#xff0c;如果您有打印机&#xff0c;并且已经成功和华为手机相连&#xff0c;在解决上就要容易很多。 具体操作如下&#xff1a; 选择文件 文件来源&#xff1a;华为手机上的文件可以来自多个应用&#xff0c;如图库、备忘录、文件管理等&#xf…

20240628模拟赛总结

cf好了 让我们开始 T1 Two Regular Polygons 判断能不能构造出题中要求的正多边形 关键是n%m0 Two Regular Polygons #include<bits/stdc.h> using namespace std; int t; int n,m; int main() {cin>>t;for(int i1;i<t;i){cin>>n>>m;if(n%m0)co…

MySQL——事务ACID原则、脏读、不可重复读、幻读

什么是事务 要么都成功&#xff0c;要么都失败 一一一一一一一 1. SQL执行&#xff1a;A给B转账 A 1000 ---->200 B 200 2. SQL执行&#xff1a;B收到A的钱 A 800 B 400 一一一一一一一 将一组SQL放在一个批次中去执行~ 事务原则&#xff1a;ACI…

学习笔记(linux高级编程)10

IPC 进程间通信 interprocess communicate 三大类&#xff1a; 1、古老的通信方式 无名管道 有名管道 信号 2、IPC对象通信 system v BSD suse fedora kernel.org 消息队列(用的相对少&#xff0c;这里不讨论) 共享内存 信号量集 3、socket通信 网络通信 特…

TF/IDF算法

第1关&#xff1a;去除停用词 任务描述 本关任务&#xff1a;根据本关所学有关停用词的知识&#xff0c;编写使用停用词表去除停用词的程序并通过测试用例。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 停用词的意义&#xff1b; 去除停用词的步骤。 …

浅谈Web性能测试(原创)

一、性能测试不是什么高技术的活&#xff1a; 说到性能测试&#xff0c;很多工作时间较短的新同事或者应届生就很害怕。 为什么害怕&#xff0c;因为感觉无从下手&#xff0c;不知道该做什么、怎么做、做到什么程度&#xff1f; 一听性能测试首先想到的是各种专业的性能测试…

ThingsKit物联网平台功能解析

随着物联网技术的飞速发展&#xff0c;各种物联网平台应运而生&#xff0c;为设备管理和数据集成提供了强大的支持。ThingsKit物联网平台以其全面的功能和灵活的配置&#xff0c;成为行业中的一大亮点。本文将详细解析ThingsKit物联网平台的功能清单&#xff0c;带您深入了解该…

oracle数据库默认表空间详解

文章目录 oracle数据库默认表空间列表 oracle数据库默认表空间列表 系统表空间&#xff08;System Tablespace&#xff09; 系统表空间包含了系统级别的元数据&#xff0c;如数据字典、系统表和存储过程等。例如SYSTEM表空间用于保存数据库的数据字典、PL/SQL程序的源代码和解释…

【C语言】分支(选择)和循环语句

目录 简述选择语句简述if语句单if结构语法格式 if-else结构语法结构 语法结构 循环结构break和continuewhile循环语法结构 for循环语法结构 do while循环语法结构 简述 在c语言中分支和循环语句是极其重要的&#xff0c;就像生活中你难免要做一些判断和循环往复做一些事。 选…

SpringBoot 中的参数校验:构建健壮应用的基石

前言 在开发Web应用时&#xff0c;处理用户输入是不可避免的一环。然而&#xff0c;用户输入往往充满不确定性&#xff0c;可能是格式不正确、类型不匹配&#xff0c;甚至包含恶意内容。为了确保应用的稳定性和安全性&#xff0c;对输入参数进行有效校验显得尤为重要。Spring …

【触想智能】工业平板电脑在新能源领域上的应用分析

工业平板电脑是一种具有高性能和稳定性的计算机设备&#xff0c;适用于在恶劣环境下进行数据采集、运营管理和现场操作。 随着新能源技术的快速发展&#xff0c;工业平板电脑不断地得到应用&#xff0c;并且已成为新能源领域中的重要工具之一。本文将从四个方面探讨工业平板电脑…

WSO2 products 文件上传漏洞(CVE-2022-29464)

前言 CVE-2022-29464 是一个影响多个 WSO2 产品的严重远程代码执行&#xff08;RCE&#xff09;漏洞。这些产品包括 WSO2 API Manager、WSO2 Identity Server 和 WSO2 Enterprise Integrator 等。由于用户输入验证不当&#xff0c;该漏洞允许未经身份验证的攻击者在服务器上上…

代码随想录算法训练营第九天|151.翻转字符串里的单词、右旋字符串、28. 实现 strStr()、459.重复的子字符串

打卡Day9 1.151.翻转字符串里的单词2.右旋字符串3.28. 实现 strStr()4.459.重复的子字符串 1.151.翻转字符串里的单词 题目链接&#xff1a;翻转字符串里的单词 文档讲解&#xff1a; 代码随想录 思路&#xff1a;首先&#xff0c;移除多余的空格&#xff1b;然后&#xff0c…

TensorRT学习(二)TensorRT使用教程(Python版)

本文适合快速了解TensorRT使用的整体流程,具体细节还是建议参考TensorRT的官方文档。 加速原理: 加速原理比较复杂,它将会根据显卡来优化算子,以起到加速作用(如下图所示)。简单的来说,就是类似于你出一个公式1+1+1,而你的显卡支持乘法,直接给你把这个公式优化成了1*…

生成式AI赋能金融信贷:减少信用评分偏差

信用评分在确定谁获得信贷以及以何种条件获得信贷方面发挥着关键作用。然而&#xff0c;尽管这一点很重要&#xff0c;但传统的信用评分系统长期以来一直受到一系列关键问题的困扰——从偏见和歧视&#xff0c;到有限的数据考虑和可扩展性挑战。例如&#xff0c;一项针对美国贷…

【代码随想录】【算法训练营】【第56天】 [卡码98]所有可达路径

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 56&#xff0c;周二&#xff0c;继续ding~ 题目详情 [卡码98] 所有可达路径 题目描述 卡码98 所有可达路径 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言…