elasticsearch - Elasticsearch 自定义地理距离过滤器
问题描述
从 Elasticsearch 查询中,我想检索可变距离内的所有点。假设我有 2 家商店,一家愿意在最长 3 公里的范围内送货,另一家愿意在最长 5 公里的范围内送货:
PUT /my_shops/_doc/1
{
"location": {
"lat": 40.12,
"lon": -71.34
},
"max_delivery_distance": 3000
}
PUT /my_shops/_doc/2
{
"location": {
"lat": 41.12,
"lon": -72.34
},
"max_delivery_distance": 5000
}
对于给定的位置,我想知道哪些商店可以送货。如果给定位置在 3 公里以内,IE 查询应该返回 shop1,如果给定位置在 5 公里以内,则返回 shop2
GET /my_shops/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": max_delivery_distance,
"location": {
"lat": 40,
"lon": -70
}
}
}
}
}
}
解决方案
我认为您需要使用脚本才能使用另一个字段作为参数。经过一番研究,我得出了这个答案:
GET my_shops/_search
{
"query": {
"script": {
"script": {
"params": {
"location": {
"lat": 40,
"lon": -70
}
},
"source": """
return doc['location'].arcDistance(params.location.lat, params.location.lon)/1000 <= doc['max_delivery_distance'].value"""
}
}
}
}
基本上,我们利用与 GEO 点相关的类在无痛https://github.com/elastic/elasticsearch/pull/40180/中列入白名单的事实,并且脚本接受其他参数(您的固定位置)。
根据 arcDistance 的文档,我们以米为单位检索大小,因此您需要将该值除以 1000 转换为 km。
附加说明
我假设 location 和 max_delivery_distance 总是(对于每个文档)定义的。如果不是这种情况,您需要覆盖这种情况。
参考
推荐阅读
- date-formatting - 如何在 Pentaho Data Integrity CE 中将字符串年月转换为 2018-12-01 格式的完整日期
- python - python如何将数组分成随机大小
- android - 用于持续、频繁更新通知的最先进方法(“通知小部件”)
- c - 仅使用 read() 和 open() 系统调用获取文件/目录的路径并遍历目录和子目录中的所有文件
- python - Tensorflow Dst 张量未初始化。当使用 tf.Saver()
- docker - 如何在 docker 中安装 nginx 1.14.X?
- dialogflow-es - DialogFlow:在上下文冲突时控制意图识别
- javascript - 发送自定义标头和 cookie
- git - git删除并添加同一行
- javascript - AWS API 网关、Lambda、JavaScript CORS