首页 > 编程知识 正文

elastic是什么,elasticsearch实战与原理解析

时间:2023-05-04 16:53:02 阅读:161554 作者:720

Kibana提供了一种用于搜索和可视化存储在Elasticsearch中的数据的强大方法。 为了实现可视化,Kibana会搜索Elasticsearch mapping中定义的field,并将它们以图表形式作为选择呈现给用户。 但是,如果忘记在方案中将重要值定义为单独的字段,会怎么样呢? 或者,如果我想合并两个字段,该怎么办? 可以使用Kibana编写field脚本。

实际上,脚本化的field最早出现在Kibana 4初期。 当时只能依靠Elasticsearch中专门处理数值的脚本语言Lucene Expressions来定义它们。 因此,脚本化字段的功能只能在有限的用例集中发挥。 在Kibana 5.0中,Elasticsearch引入了Painless。 这是一种安全、功能强大的脚本语言,可以操作各种数据类型,因此Kibana 5.0脚本字段功能更强大。

接下来,该博客将介绍如何为典型用例创建脚本式field。 在此期间,我们依靠Kibana入门教程的数据集,使用运行在可免费加速的Elastic Cloud上的Elasticsearch和Kibana实例。

脚本化字段的结构

Elasticsearch允许您为每个请求指定脚本化的字段。 Kibana在此基础上进行了改进,现在可以在后续用户界面的多个位置使用,方法是在“管理”区域中定义脚本化字段。 Kibana将脚本字段与. Kibanaindex中的其他配置一起保存,但此配置专用于Kibana,Elasticsearch的API用户无权访问Kibana脚本字段

甜熊猫要在Kibana上定义脚本化字段,必须选择脚本语言。 可以从Elasticsearch节点上安装的所有启用动态脚本的语言中进行选择。 缺省情况下,5.0选项有" expression "和" painless ",2.x选项只有" expression "。 也可以安装其他脚本语言来启用动态脚本,但由于无法充分封装沙箱,因此不推荐使用。

脚本字段一次可以处理一个Elasticsearch文档,但可以在此文档中引用多个字段。 因此,可以使用脚本字段将多个字段合并或转换为一个文档,但不能对多个文档执行计算,如时间序列运算。 Painless和Lucene expressions都可以对存储在doc_values中的field执行操作。 因此,处理字符串数据时,必须将字符串存储在keyword数据类型中。 基于Painless的脚本字段也不能直接与_source进行操作。

在Management (管理)区域中定义脚本化的field后,用户可以参考与Kibana其他部分的其他field的交互方法,用同样的方法与脚本化的field进行交互。 脚本字段将自动显示在“发现”、“发现”和“字段”列表中,并可在“可视化”中用于创建可视化。 Kibana只是在查询时将脚本化的field定义传递给Elasticsearch进行评估。 结果数据集将与从Elasticsearch返回的其他结果合并,并以表格或图表的形式显示给用户。

写这个博客时,脚本化字段的使用有已知的限制。 可以将kibanavisualization生成器中可用的大多数Elasticsearch聚合应用于脚本字段。 除了最有名的significant terms aggregation (重要术语的汇总)。 也可以使用“Discover”、“Visualize”和“Dashboard”过滤栏过滤脚本化字段,但要小心编写相应的脚本,使相应的值返回到定义的值,如下所述此外,为了避免在使用脚本字段时破坏环境的稳定性,请确保参考以下“最佳实践”一章。

脚本化字段示例本节提供了Kibana典型场景中的Lucene expressions和Painless脚本化字段的示例。 如上所述,这些示例基于Kibana入门教程的数据集,在以前的版本中,由于某些类型的脚本字段存在与过滤和排序相关的已知问题,因此使用了Elasticsearch和Kibana

由于Elasticsearch 5.0缺省情况下启用了Lucene expressions和Painless,因此脚本fields在大多数情况下应该可以立即使用。 唯一的例外是需要基于正则表达式分析fields的脚本。 这些脚本必须在elasticsearch.yml中设置以下设置,以打开Painless正则表达式匹配: script.painless.regex.enabled 3360 true

p> 对单个 field 执行计算 示例:由字节计算出千字节语言:expressions返回类型:数字 doc['bytes'].value / 1024

注意:切记 Kibana 脚本化 fields 一次只能处理一个单独的文档,因此无法在脚本化 fields 中进行时间序列运算。

返回数字的日期运算 示例:将日期解析成小时时间语言:expressions返回类型:数字

Lucene expressions 提供了大量开箱即用的 日期处理函数。但是,由于 Lucene expressions 只能返回数字值,因此我们必须使用 Painless 来返回基于字符串的星期值(如下所示)。

doc['@timestamp'].date.hourOfDay

注意:上面的脚本将返回 1-24

doc['@timestamp'].date.dayOfWeek

注意:上面的脚本将返回 1-7

合并两个字符串值 示例:合并源和目标或名字和姓氏语言:painless返回类型:字符串 doc['geo.dest.keyword'].value + ':' + doc['geo.src.keyword'].value

注意:由于脚本化 field 需要操作doc_values中的 field,因此我们上面使用的是 .keyword 版本的字符串。

引入逻辑运算 示例:为所有超过 10000 字节的文档返回标签“big download”语言:painless返回类型:字符串 if (doc['bytes'].value > 10000) { return "big download";}return "";

注意:引入逻辑运算时,确保每个执行路径都具有良好定义的返回语句和良好定义的返回值(而非 null)。例如,在 Kibana 过滤器中使用上述脚本化 field 时,如果最后没有返回语句或者语句返回 null,都会出现编译错误。另外还请注意,Kibana 脚本化 field 中不支持将逻辑运算分解成函数。

返回子串 示例:返回 URL 中最后一个斜线后面的部分语言:painless返回类型:字符串 def path = doc['url.keyword'].value;if (path != null) { int lastSlashIndex = path.lastIndexOf('/'); if (lastSlashIndex > 0) { return path.substring(lastSlashIndex+1); }}return "";

注意:尽量避免使用正则表达式提取子串,因为 indexOf() 操作占用的资源更少,更不易出错。

使用正则表达式匹配字符串,并对匹配进行操作 示例:如果在 field“referer”中找到子串“error”,则返回字符串“error”,否则返回字符串“no error”。语言:painless返回类型:字符串if (doc['referer.keyword'].value =~ /error/) { return "error"} else {return "no error"}

注意:简化的正则表达式语法对基于正则表达式匹配的条件句有用。

匹配字符串并返回该匹配 示例:返回域,即 field “host”中最后一个点后面的字符串。语言:painless返回类型:字符串def m = /^.*.([a-z]+)$/.matcher(doc['host.keyword'].value);if ( m.matches() ) { return m.group(1)} else { return "no match"}

注意:通过正则表达式 matcher() 函数定义对象,可以提取与正则表达式相匹配的字符组并将它们返回。

匹配数字并返回该匹配 示例:返回 IP 地址的第一个八位组(存储为字符串)并将它视为一个数字。语言:painless返回类型:数字 def m = /^([0-9]+)..*$/.matcher(doc['clientip.keyword'].value);if ( m.matches() ) { return Integer.parseInt(m.group(1))} else { return 0}

注意:在脚本中返回正确的数据类型是很重要的。正则表达式匹配返回的是字符串,即便匹配的是数字依然返回字符串,因此返回时应该显式地将它转换成整数。

返回字符串的日期运算 示例:将日期解析成星期值再解析成字符串语言:painless返回类型:字符串LocalDateTime.ofInstant(Instant.ofEpochMilli(doc['@timestamp'].value), ZoneId.of('Z')).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault())

注意:由于 Painless 支持 Java 所有的原生类型,因此通过它可以获取与这些类型相关的原生函数,例如LocalDateTime(),这在执行更加高级的日期运算时有用。

最佳实践

如你所见,Painless 脚本化语言提供了一些强大的方法,能够通过 Kibana 脚本化 field 从存储在 Elasticsearch 中的任意 field 提取出有用的信息。但是,能力越大,责任越大。

接下来,我们将围绕 Kibana 脚本化 field 的使用,简要地介绍了一些最佳实践。

始终使用开发环境测试脚本化 field。由于你在 Kibana 的 Management(管理)区域保存脚本化 field 之后,它们就会立即激活(例如:它们会出现该索引模式的 Discover(探索)界面,供所有用户使用),因此不应该直接在生产环境中开发脚本化 field。我们建议先在开发环境中试用你的语法,在模拟环境中评估脚本化 field 对实际数据集和数据卷的影响,然后才能将它们提升到生产环境。甜美的小熊猫相信脚本化 field 能够为你的用户提供价值时,可以考虑对你的 ingest 进行修改,以便在索引时从 field 中提取新数据。这将节省 Elasticsearch 在查询时的处理工作量,并且将为 Kibana 用户实现更快的响应时间。你还可以使用 Elasticsearch 中的 _reindex API 重新索引现有数据。

 

源文章链接地址

附:elasticsearch painless脚本API

 

demo String Content = doc['Content'].value;if (Content != null) { int lastExMarkIndex = Content.lastIndexOf('!'); if (lastExMarkIndex > 0) { Content = Content.substring(lastExMarkIndex+1) } int commaMarkIndex = Content.indexOf(','); while (commaMarkIndex>0){ String beforeSubString = Content.substring(0,commaMarkIndex); Content = Content.substring(commaMarkIndex+1); int markIndex = beforeSubString.indexOf(':'); if (markIndex > 0){ String key = beforeSubString.substring(0,markIndex); if (key.trim()=='type'){ return beforeSubString.substring(markIndex+1); } } commaMarkIndex = Content.indexOf(','); } return 'Other';}else {return 'Other';}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。