首先,我想说的是这篇文章是我之前的一篇文章“Beats:运用Elastic Stack分析COVID-19数据并进行可视化分析”的续集。在今天的这篇文章中,我们来针对中国区域里的疫情按照每个省来进行展示数据。这个在之前的教程里是缺失的。这个也就是regional map。如果大家想对regional map感兴趣的话,可以参阅我之前的另外一篇文章“Kibana:在Kibana中定制Regional Map”来了解如何定制一个regional map。
在之前的索引中covid,由于一些原因,那个city应该理解为province。当初在解析数据的时候,由于有外国的数据,当时没有注意到这个。在这里纠正一些。
运用Kibana查看covid19索引
GET covid19/_search
{
"query": {
"match": {
"country": "China"
}
}
}
我们通过上面的查询,可以找到所有China的文档:
如我前面所述的,由于一些原因city在我们的文档中应该理解为省,也即province。如上图所示,它显示了一个city为Hubei的文档。那么我们该如何在地图中显示这个数据呢?答案是regional map。通过regional map,我们可以把整个湖北省在地图上显示出来,并显示在这个省里的疫情信息。
EMS
EMS 也即Elastic Map Service。我们可以打开EMS:https://maps.elastic.co/v7.6/index.html?locale=en#file/china_provinces:
我们要记得在左边可以选择我们想要的region。如图所示,上面显示中国地区的所有region。我们可以同时发现在下面的Guangxi Zhuang Autonomous Region。显然这个名字和我们的数据中的Guangxi是不相符的。同时,我还发现Ningxia Hui Autonomous Region在我们的数据表格中是Ningxia,Taiwan Province为Taiwan。为了能够正确把数据在EMS中做显示,我们必须对这几个数据做分别处理。那么我们该如何做呢?
运用script processor对city字段进行处理
Script processor允许我们在Pipeline中对我们的数据运行一段脚本,并对它们进行处理。为此,我们重新设计我们的pipleline:
PUT _ingest/pipeline/covid19_parser
{
"processors": [
{
"remove": {
"field": ["log", "input", "ecs", "host", "agent"],
"if": "ctx.log != null && ctx.input != null && ctx.ecs != null && ctx.host != null && ctx.agent != null"
}
},
{
"gsub": {
"field": "message",
"pattern": "\"",
"replacement": "'"
}
},
{
"grok": {
"field": "message",
"patterns": [
"%{NUMBER:lat:float},%{NUMBER:lon:float},'%{DATA:address}',%{DATA:city},',',%{DATA:country},%{NUMBER:infected:int},%{NUMBER:death:int}"
]
}
},
{
"set": {
"field": "location.lat",
"value": "{{lat}}"
}
},
{
"set": {
"field": "location.lon",
"value": "{{lon}}"
}
},
{
"script": {
"source": """
if(ctx.city == "Taiwan") {
ctx.city = "Taiwan Province"
}
if(ctx.city == "Ningxia") {
ctx.city = "Ningxia Hui Autonomous Region"
}
if(ctx.city == "Guangxi") {
ctx.city = "Guangxi Zhuang Autonomous Region"
}
"""
}
}
]
}
请注意上面的script脚本部分。它帮我们检测city字段是否为Taiwan,如果是的话,那么就用Taiwn Province来代替。等我们执行完上面的pipeline后,我们再次执行如下的代码:
POST covid19/_update_by_query?pipeline=covid19_parser
经过上面的pipeline的执行后,我们的数据就变成为我们所希望的那样:
GET covid19/_search?size=100
{
"query": {
"match": {
"city": "Guangxi Zhuang Autonomous Region"
}
}
}
显示的数据为:
"hits" : [
{
"_index" : "covid19",
"_type" : "_doc",
"_id" : "jYcqEHEBPWmYf6MmsLsg",
"_score" : 5.634789,
"_source" : {
"country" : "China",
"infected" : 254,
"address" : "Guangxi, China",
"death" : 2,
"city" : "Guangxi Zhuang Autonomous Region",
"lon" : 109.0,
"message" : "24,109,'Guangxi, China',Guangxi,',',China,254,2,250",
"@timestamp" : "2020-03-25T05:29:23.668Z",
"location" : {
"lon" : "109.0",
"lat" : "24.0"
},
"lat" : 24.0
}
}
]
至此,我们的数据完全符合我们的要求。在下面,我们利用EMS来对每个省或地区进行展示。
运用EMS来展示数据
我们首先打开我们之前的Dashboard:
我们点击Map右上角的设置图标,然后点击Edit map:
我们想在当前的图层中添加一个图层:
我们选择EMS Boundaries:
在上面我们要选择China Provinces。点击Add layer:
在上面我们选择name (zh),这样可以显示中文的名字。我们点击and use metric后,显示:
我们想显示是每个省的总感染数,而不是默认情况先的文档的count。我们接着向下滚动:
我们点击Save & close:
在上面点击Save。这样我们就完成了对map的修改。如果我们点击湖北省的话,我们可以看到:
更新后的Dashboard显示为:
在今天的教程中,我没有使用World map为其它的地区做regional map。这其中可能有一些city字段的值和EMS中的不太一样。我就不做了。如果你感兴趣的话,可以尝试一下。这个练习就留给你们了。