Logstash:导入zipcode CSV文件和Geo Search体验

在今天的文章中,我们来做一个简单的Logstash体验,并体验Geo Search。我们的数据是中国区里的所有的zipcode,也就是邮政编码。

安装

如果你还没有安装自己的Elastic Stack:

在上面的安装中,我们都是安装默认缺省的方式来进行安装的。Elasticsearch运行于localhost:9200,而Kibana运行于localhost:5601上。

下载数据

我们通过如下的命令来下载我们数据:

git clone https://github.com/liu-xiao-guo/elasticzipcodes

通过上面的下载,我们可以得到一个叫做zipcodes.csv的文件。它的文件的内容如下:

从上面的表格中,我们可以看到:在这个zipcodes.csv的文件中,它含有Id, Code, AreaCode, Name, ShortName, Logitude, Latitude, Sort, Memo, Disabled字段。我们把这个下载的文件置于我们喜欢的一个文件目录中。

导入数据

为了把这数据导入到Elasticsearch中,我们使用Logstash。为此,我们写一个我们自己的logstash配置文件:

logstash_zipcodes.conf

input {
	file {
		path => "/Users/liuxg/data/zipcodes/zipcodes.csv"
		start_position => "beginning"
		sincedb_path => "/dev/null"
	}
}


filter {
	csv {
		separator => ","
		columns => ["Id", "Code", "AreaCode", "Name", "ShortName", "Longitude", "Latitude", "Sort", "Memo", "Disabled"]
	}

	mutate {
		convert => {"Longitude" => "float"}
		convert => {"Latitude" => "float"}
		add_field => ["location", "%{Latitude},%{Longitude}"]
		rename => ["Code", "zipcode"]
	}
}


output {
	stdout {codec => rubydebug}

	elasticsearch {
		index => "zipcodes"
		hosts => ["http://localhost:9200"]
	}
}

我们知道Logstash的管道由三个部分组成:inputs,filters及outputs。

在上面的input部分,我们使用file来输入我们指定路径的文件zipcodes.csv。根据你自己的实际的这个文件的路径,我们需要做相应的调整。

在filters部分,我们通过csv过滤器来提前相应的字段。同时我们使用mutate过滤器来对我们的数据进行类型的转换及重新命名。我们通过add_fields来创建一个新的字段叫做location,它由经纬度组成。

在我们的输出部分,我们通过stdout输出到我们的标准输出。这在很多的情况下,可以帮助我们调试我们的Logstash管道很用用。同时,我们把输出导入到我们的本地的Elasticsearch中。我们的数据将会保存于一个叫zipcodes的索引中。

为了能够使Elasticsearch帮我们生产的的zipcodes能适合我们的需求,我们在Kibana中打入如下的命令:

PUT _template/zipcodes
{
  "order": 10,
  "index_patterns": [
    "zipcodes*"
  ],
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "zipcode": {
        "type": "text"
      },
      "location": {
        "type": "geo_point"
      }
    }
  },
  "aliases": {}
}

上面索引template表明:但凡index pattern为zipcodes*的索引将具有以上所定义的settings,mappings及alias。在上面,我们把我们的location定义为一个geo_point的数据类型。

我们可以通过如下的命令来启动Logstash:

sudo ./bin/logstash -f ~/data/zipcodes/logstash_zipcodes.conf

等我们的Logstash启动后,我们可以在terminal中看到如下的输出

从上面我们看出Logstash帮我们生产的各种字段。

我们可以打开我们的Kibana,并打入如下的指令:

GET zipcodes/_count

我们可以看到如下的结果:

{
  "count" : 42358,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  }
}

在上面,我们可以看到我们有42358个文档。

搜索数据 - Geo search

在上面我们已经看到我们导入的Geo数据,我们可以通过如下的命令来对我们的数据进行查询:

GET zipcodes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": {
        "geo_distance": {
          "distance": "1km",
          "location": {
            "lat": 39.920086,
            "lon": 116.454182
          }
        }
      }
    }
  }
}

在上面,我们查询在以坐标(116.454182, 39.920086)我中心方圆一公里的所有文档。显示的结果是:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "zipcodes",
        "_type" : "_doc",
        "_id" : "rvG12HABqA-NWEvj7Dj0",
        "_score" : 1.0,
        "_source" : {
          "Memo" : null,
          "Latitude" : 39.920929,
          "Name" : "呼家楼街道",
          "message" : "35,110105003,110105,呼家楼街道,呼家楼街道,116.464325,39.920929,16,,false",
          "Sort" : "16",
          "host" : "liuxg",
          "AreaCode" : "110105",
          "location" : "39.920929,116.464325",
          "path" : "/Users/liuxg/data/zipcodes/zipcodes.csv",
          "ShortName" : "呼家楼街道",
          "Id" : "35",
          "Longitude" : 116.464325,
          "@version" : "1",
          "@timestamp" : "2020-03-14T11:02:43.681Z",
          "zipcode" : "110105003",
          "Disabled" : "false"
        }
      }
    ]
  }

当然,我们也可以修改上面的distance来调整,从而得到更多的结果。

同样的,我们也可以针对定义好的一个长方形区域来进行搜索:

GET zipcodes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 39.94086,
              "lon": 116.454182
            },
            "bottom_right": {
              "lat": 39.930086,
              "lon": 116.464182
            }
          }
        }
      }
    }
  }
}

在上面,我们定义了两个坐标位置。这两个位置定义了一个矩形的区域。上面的搜索将显示在这个区域里的所有的文档:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "zipcodes",
        "_type" : "_doc",
        "_id" : "MfG12HABqA-NWEvj7Diy",
        "_score" : 1.0,
        "_source" : {
          "Memo" : null,
          "Latitude" : 39.931461,
          "Name" : "团结湖街道",
          "message" : "45,110105013,110105,团结湖街道,团结湖街道,116.462578,39.931461,35,,false",
          "Sort" : "35",
          "host" : "liuxg",
          "AreaCode" : "110105",
          "location" : "39.931461,116.462578",
          "path" : "/Users/liuxg/data/zipcodes/zipcodes.csv",
          "ShortName" : "团结湖街道",
          "Id" : "45",
          "Longitude" : 116.462578,
          "@version" : "1",
          "@timestamp" : "2020-03-14T11:02:43.684Z",
          "zipcode" : "110105013",
          "Disabled" : "false"
        }
      }
    ]
  }

上面显示的结果是在我们定义的区域里的所有的文档。

展示数据

在上面我们可以很方便地搜索我们的数据。我们同时也可以使用Kibana提供的强大的图像化工具来展示我们所有的文档。为此,我们首先来创建一个叫做zipcodes的index pattern:

点击上面的 “Create index pattern”:

点击上面的“Next step”按钮:

因为这个不是一个时序的文档,所以我们选择 “I don't want to use the Timer Filter”。点击“Create index pattern”:

这样我们就创建了我们的zipcodes* index pattern。

接下来我们为我们的zipcodes创建一个Visualization:

点击上面的 “Create visualization”按钮:

我们选择 “Maps”:

点击上面的“Add layer”按钮:

点击上面的 “Documents”:

点击上面的“Add layer”:

我们添加tooltips为zipcode及ShortName:

点击上面的“Save & close”按钮:

我们从上面可以看到所有的文档都显示在地图的中国的位置。我们放大我们的地图,可以看到如下的画面:

当我们的鼠标放置于一个文档上后,它就可以显示出当前位置的名字及zipcode。

我们可以同时利用地图上面的工具来定义一个我们想要的区域来进行搜索:

我们通过运用鼠标来进行定义一个区域:

选择Draw shape:

我们可以在我们喜欢的区域用鼠标来标出我们想搜索的区域,最终我们形成一个filter,从而只显示出该区域里的文档:

选择上面的filter:location in shape:

选择上面的Edit filter,我们可以看到:

在上面我们可以看到用DSL搜索所需要的geo_polygon用到的点:

GET zipcodes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": {
        "geo_polygon": {
          "ignore_unmapped": true,
          "location": {
            "points": [
              {
                "lat": 40.05915,
                "lon": 115.95216
              },
              {
                "lat": 39.86638,
                "lon": 116.22583
              },
              {
                "lat": 40.08309,
                "lon": 116.31184
              },
              {
                "lat": 40.05915,
                "lon": 115.95216
              }
            ]
          }
        }
      }
    }
  }
}

上面的查询的结果将显示13个文档:

  "hits" : {
    "total" : {
      "value" : 13,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "zipcodes",
        "_type" : "_doc",
        "_id" : "svG12HABqA-NWEvj7Dj0",
        "_score" : 1.0,
        "_source" : {
          "Memo" : null,
          "Latitude" : 39.916122,
          "Name" : "八角街道",
          "message" : "99,110107003,110107,八角街道,八角街道,116.195648,39.916122,2,,false",
          "Sort" : "2",
          "host" : "liuxg",
          "AreaCode" : "110107",
          "location" : "39.916122,116.195648",
          "path" : "/Users/liuxg/data/zipcodes/zipcodes.csv",
          "ShortName" : "八角街道",
          "Id" : "99",
          "Longitude" : 116.195648,
          "@version" : "1",
          "@timestamp" : "2020-03-14T11:02:43.694Z",
          "zipcode" : "110107003",
          "Disabled" : "false"
        }
      },
      {
        "_index" : "zipcodes",
        "_type" : "_doc",
        "_id" : "MfG12HABqA-NWEvj7Tk5",
        "_score" : 1.0,
        "_source" : {
          "Memo" : null,
          "Latitude" : 40.003696,
          "Name" : "军庄镇",
          "message" : "143,110109104,110109,军庄镇,军庄镇,116.103455,40.003696,5,,false",
          "Sort" : "5",
          "host" : "liuxg",
          "AreaCode" : "110109",
          "location" : "40.003696,116.103455",
          "path" : "/Users/liuxg/data/zipcodes/zipcodes.csv",
          "ShortName" : "军庄镇",
          "Id" : "143",
          "Longitude" : 116.103455,
          "@version" : "1",
          "@timestamp" : "2020-03-14T11:02:43.704Z",
          "zipcode" : "110109104",
          "Disabled" : "false"
        }
      },
      {
        "_index" : "zipcodes",
        "_type" : "_doc",
        "_id" : "KfG12HABqA-NWEvj7Tqx",
        "_score" : 1.0,
        "_source" : {
          "Memo" : null,
          "Latitude" : 39.898903,
          "Name" : "八宝山街道",
          "message" : "97,110107001,110107,八宝山街道,八宝山街道,116.231972,39.898903,1,,false",
          "Sort" : "1",
          "host" : "liuxg",
          "AreaCode" : "110107",
          "location" : "39.898903,116.231972",
          "path" : "/Users/liuxg/data/zipcodes/zipcodes.csv",
          "ShortName" : "八宝山街道",
          "Id" : "97",
          "Longitude" : 116.231972,
          "@version" : "1",
          "@timestamp" : "2020-03-14T11:02:43.694Z",
          "zipcode" : "110107001",
          "Disabled" : "false"
        }
      },
      ...
    ]
   ...

 我们可以把当前的Visualization保存下来以在Dashboard里进行使用:

选择Save,最终,我们形成自己的Dashboard:

展开阅读全文

没有更多推荐了,返回首页

应支付0元
点击重新获取
扫码支付

支付成功即可阅读