所以,这是我们的用例:
我们有一个摄取过程,每天将大约 1000 个元素加载到 ES 索引中。该索引的字段之一是城市名称,但我们想详细说明一些包含城市元素的地图,但我们没有这些城市的地理位置。
通常我们的数据城市来自非常有限的集合,但是(这是一个很大的但是)我们可以时不时地从完全意想不到的地方获得新的城市。因此,我们不需要世界上每个城市的确切索引及其地理位置(正如您可以从地理名称中获得的那样),但我们肯定必须不时检查几个城市的地理位置。
说起来,我的做法是这样的: 我想在我们的logstash ETL过程中添加一个在ES索引中查找城市的查询,如果该城市在那里,它可以从这个城市索引中获取它的地理位置,如果没有,我想查询geonames API来查找城市的地理位置,并将其存储在我们的 ES 城市索引中。这样,我们只需要时不时地查询新城市的 API,一旦某个城市被纳入我们的城市索引,我们就不必再次查询它。
对于 ELK 来说这是一个好方法吗?或者还有我没有看到的更好的方法?请记住,我是 ELK 堆栈的新手。
您的方法对您的用例有意义,并且这是在 Elasticsearch 和 ELK(Elasticsearch、Logstash 和 Kibana)堆栈中处理地理位置数据的合理方法。以下是一些可帮助您实施的注意事项和步骤:
创建城市索引: 首先在 Elasticsearch 中创建索引来存储您的城市地理位置数据。该索引可以包含
city_name
、latitude
、longitude
等字段。
摄取城市数据: 使用您已知的城市的地理位置数据填充此索引。您可以手动输入此数据或使用自动化流程。
Logstash ETL 流程: 在 Logstash ETL 流程中,当您遇到带有城市名称的新元素时,请在城市索引中执行查找。如果找到该城市,请使用其地理位置。如果没有,请查询 geonames API 以获取地理位置,然后将其存储在您的城市索引中。
Logstash 配置示例:
filter {
if ![geo_location] {
elasticsearch {
hosts => ["your_elasticsearch_host"]
index => "cities"
query => "city_name:%{[city_field]}"
fields => { "geo_location" => "geo_location" }
add_field => { "city_found" => "true" }
}
}
}
output {
if [city_found] != "true" {
http {
url => "https://api.geonames.org/searchJSON?q=%{[city_field]}&username=your_geonames_username"
verb => "GET"
target_body => "[geo_location]"
}
elasticsearch {
hosts => ["your_elasticsearch_host"]
index => "cities"
document_id => "%{[city_field]}"
}
}
}
根据您的实际字段名称、URL 和 API 密钥调整配置。
定期更新: 设置定期作业来检查新城市并更新您的城市索引。这可以通过使用 cron 或作业调度程序等工具的计划任务来完成。
索引模板: 考虑为您的城市索引定义一个索引模板,以确保未来文档的一致映射。
请记住,geonames API 可能有速率限制,因此请注意查询它的频率。此外,请确保在 API 无法访问或返回意外响应的情况下妥善处理错误。
此方法允许您维护已知城市地理位置的本地索引,同时根据需要动态添加新城市。这是处理预期和意外城市数据的实用解决方案。