【Elastic Engineering】Elasticsearch:创建 Runtime field 并在 Kibana 中使用它 - 7.11 发布

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch:创建 Runtime field 并在 Kibana 中使用它 - 7.11 发布

作者:刘晓国


在之前的文章 “Elasticsearch:使用 Runtime fields 对索引字段进行阴影处理以修复错误 - 7.11 发布”,我展示了如何使用 runtime field 来 shadow 一个已有的在 mapping 中的字段,比如 duration。在今天的练习中,我将展示如何创建一个崭新的字段并进行数据的统计。在这里请注意的是:新增加的 runtime field 并不在 source 中添加,而只是在查询时生成的,也即 schema on read。


在接下来的练习中,它包含创建 runtime field 的演示,其中从包含日期的时间戳字段中计算星期几。 然后使用索引字段和新创建的 runtime field 在 Kibana Lens 中创建可视化文件。 Runtime field 是在 Elasticsearchimage.png 中读取时为 schema 的实现提供的名称。

展示


我们先来创建一个 index mapping:

#Create the index mapping
PUT date_to_day
{
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date",
        "format": "yyyy-MM-dd"
      },
      "response_code": {
        "type": "integer"
      }
    }
  }
}

在上面,我们展示了两个字段: timestamp 以及  response_code。由于有一个时间戳,我们可以从这个时间戳中导出时间所在的 day of week,也就是星期几。这个对于我们想对一周的每一天统计非常有用。


我们通过如下的 bulk API  来导入数据:

#Load a few documents to work with
POST date_to_day/_bulk
{"index":{}}
{"response_code": 200, "timestamp": "2021-01-01"}
{"index":{}}
{"response_code": 300, "timestamp": "2021-01-03"}
{"index":{}}
{"response_code": 200, "timestamp": "2021-01-04"}
{"index":{}}
{"response_code": 400, "timestamp": "2021-01-01"}
{"index":{}}
{"response_code": 300, "timestamp": "2021-01-05"}
{"index":{}}
{"response_code": 200, "timestamp": "2020-12-21"}
{"index":{}}
{"response_code": 200, "timestamp": "2021-01-02"}
{"index":{}}
{"response_code": 200, "timestamp": "2021-01-08"}
{"index":{}}
{"response_code": 300, "timestamp": "2021-01-09"}
{"index":{}}
{"response_code": 400, "timestamp": "2021-01-09"}

由于我们想对一周内的每一天来进行统计。一种办法是重新建立一个新的 mapping。在这个新的 mapping 里包含这个 day of week 的定义。并在数据导入之前我们对数据进行处理。在实际的使用中,面对大量的已有数据,这样的处理可能非常费力。我们可以使用 runtime field 来完成想要的功能。


在搜索请求时使用


由于 runtime field 是动态生成的,它需要计算机来进行处理。在很多的时候,我们并不想修改 mapping 来完成。我们只想针对一些搜索来进行生成这个 runtime field,或者只是作为在修改 mapping 前的一个练习来验证 runtime field  的正确性。我们使用如下的命令来生产这类的 runtime field:

#Create an ephemeral runtime field for day of week and aggregate on it
GET date_to_day/_search
{
  "runtime_mappings": {
    "day_of_week": {
      "type": "keyword",
      "script": {
        "source": """emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.SHORT, Locale.ROOT))"""
      }
    }
  },
  "size": 0,
  "aggs": {
    "terms": {
      "terms": {
        "field": "day_of_week"
      }
    }
  }
}

在上面的脚本中,我们使用 TextStyle.SHORT 来得到诸如 Fri,Sat 等文字。如果我们想得到全名,比如 Friday, Saturday,我们可以使用 TestStyle.FULL。


在上面的命令中,我们可以仔细阅读这个部分:

  "runtime_mappings": {
    "day_of_week": {
      "type": "keyword",
      "script": {
        "source": """emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.SHORT, Locale.ROOT))"""
      }
    }
  },

这个不是是使用 script 来生成一个叫做 day_of_week 的 runtime 字段。而这个字段只存在于这个搜索中。在执行完这个搜索后,这字段将自动消失。这个 day_of_week 字段是根据 timestamp 导引出来的,是之前的 mapping 中完全没有的字段。


上面命令的执行结果为:

{
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "terms" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Fri",
          "doc_count" : 3
        },
        {
          "key" : "Sat",
          "doc_count" : 3
        },
        {
          "key" : "Mon",
          "doc_count" : 2
        },
        {
          "key" : "Sun",
          "doc_count" : 1
        },
        {
          "key" : "Tue",
          "doc_count" : 1
        }
      ]
    }
  }
}

在上面显示,我们对一周内的每一天进行了统计。


在 index mapping 中使用


当然在很多的情况下,我们希望这个字段一直存在于索引的 mapping 中。这样做的好处是,我们可以在 Kibana 中的可视化中直接使用被定义的 runtime fields。通过在 mapping 定义下添加 runtime 部分并定义 Painless script,可以映射 runtime fields。 该脚本可以访问文档的整个上下文,包括原始 _source 和任何映射的字段及其值。 在查询时,脚本将运行并为查询所需的每个脚本字段生成值。


在定义要与运行时字段一起使用的 Painless script 时,必须包含 emit 以发射计算值。 例如,以下请求中的脚本从 @timestamp 字段中提取星期几,该字段定义为日期类型。 该脚本根据 timestamp 的值计算星期几,并使用 emit 返回所计算的值。


我们可以通过如下的方法来定义:

#Add the runtime field to the index mapping
PUT date_to_day/_mapping
{
  "runtime": {
    "day_of_week": {
      "type": "keyword",
      "script": {
        "source": """emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.SHORT, Locale.ROOT))"""
      }
    }
  }
}

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


boolean

date

double

geo_point

ip

keyword

long


我们可以通过如下的命令来查看 date_to_day 索引的 mapping:

{
  "date_to_day" : {
    "mappings" : {
      "runtime" : {
        "day_of_week" : {
          "type" : "keyword",
          "script" : {
            "source" : "emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.SHORT, Locale.ROOT))",
            "lang" : "painless"
          }
        }
      },
      "properties" : {
        "response_code" : {
          "type" : "integer"
        },
        "timestamp" : {
          "type" : "date",
          "format" : "yyyy-MM-dd"
        }
      }
    }
  }
}

我们到 Kibana 的 index pattern 中去创建一个索引模式并查看它的字段定义:

image.png

image.png

image.png

image.png

image.png

从上面我们可以看出来一个新增加的 day_of_week 的字段。


我们可以在 Kibana 中直接使用这个字段并进行可视化:

image.png

当然,也许你怀疑是不是索引的 source 是否已经包含新生成的 day_of_week 字段,我们可以通过如下的命令来查看:

GET  date_to_day/_search

上面的命令显示:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "date_to_day",
        "_type" : "_doc",
        "_id" : "_iyDlXcBjSpwk8PH7vNz",
        "_score" : 1.0,
        "_source" : {
          "response_code" : 200,
          "timestamp" : "2021-01-01"
        }
      },
      {
        "_index" : "date_to_day",
        "_type" : "_doc",
        "_id" : "_yyDlXcBjSpwk8PH7vNz",
        "_score" : 1.0,
        "_source" : {
          "response_code" : 300,
          "timestamp" : "2021-01-03"
        }
      },
      {
        "_index" : "date_to_day",
        "_type" : "_doc",
        "_id" : "ACyDlXcBjSpwk8PH7vRz",
        "_score" : 1.0,
        "_source" : {
          "response_code" : 200,
          "timestamp" : "2021-01-04"
        }
      },
  ...

显然,我们的 source 并没有任何的改变。 day_of_week 只是 schema image.pngon read。


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
6天前
|
消息中间件 监控 Kafka
Filebeat+Kafka+Logstash+Elasticsearch+Kibana 构建日志分析系统
【8月更文挑战第13天】Filebeat+Kafka+Logstash+Elasticsearch+Kibana 构建日志分析系统
27 3
|
1天前
|
数据可视化 Docker 容器
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
这篇文章提供了通过Docker安装Elasticsearch和Kibana的详细过程和图解,包括下载镜像、创建和启动容器、处理可能遇到的启动失败情况(如权限不足和配置文件错误)、测试Elasticsearch和Kibana的连接,以及解决空间不足的问题。文章还特别指出了配置文件中空格的重要性以及环境变量中字母大小写的问题。
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
|
5天前
|
自然语言处理 Docker 容器
ElasticSearch 实现分词全文检索 - ES、Kibana、IK分词器安装
ElasticSearch 实现分词全文检索 - ES、Kibana、IK分词器安装
10 0
|
8天前
|
Linux Docker 容器
Docker 安装 Elasticsearch、Kibana
Docker 安装 Elasticsearch、Kibana
9 0
|
23天前
|
Linux Docker 索引
ElasticSearch 通过 Kibana 与 ElasticSearch-head 完成增删改查
ElasticSearch 通过 Kibana 与 ElasticSearch-head 完成增删改查
36 0
|
2月前
|
Docker 容器
docker 运行 elasticsearch + kibana + head 集群
docker 运行 elasticsearch + kibana + head 集群
|
2月前
|
Java API 索引
必知的技术知识:Elasticsearch和Kibana安装
必知的技术知识:Elasticsearch和Kibana安装
25 0
|
3月前
|
监控 应用服务中间件 nginx
使用 Docker Compose V2 快速搭建日志分析平台 ELK (Elasticsearch、Logstash 和 Kibana)
ELK的架构有多种,本篇分享使用的架构如图所示: Beats(Filebeat) -> -> Elasticsearch -> Kibana,目前生产环境一天几千万的日志,内存占用大概 10G
210 4
|
3月前
|
运维 架构师 搜索推荐
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
52 4
|
3月前
|
安全 Linux 测试技术
在CentOS上安装Elasticsearch和Kibana
在CentOS上安装Elasticsearch和Kibana
116 0