用动态距离查询弹性搜索的地理距离

时间:2018-03-14 11:16:44

标签: elasticsearch geolocation

我正面临Elasticsearch的问题。 我想使用地理距离功能从给定的本地化中获取位于最大N km的所有项目。

这是我的数据库架构:

{
    "user_id": "abcde",
    "pin" : {
       "location" : {
           "lat" : 40.12,
           "lon" : -71.34
        }
    },
    "is_active": true,
    "action_zone": 50
}

我的查询效果非常好:

{
    "query": {
        "bool" : {
            "must" :
                [{
                    "term": {
                        "is_active": True
                    }
                }],
            "filter" : {
                "geo_distance" : {
                    "distance" : "200km",
                    "pin.location" : {
                        "lat" : 40,
                        "lon" : -70
                    }
                }
            }
        }
    }
}

现在,我想稍微修改一下这个查询,用DB中每个项目的值“action_zone”动态替换距离(在我的例子中为200km)。

如果有人可以帮助我,那将会很棒。 :)

2 个答案:

答案 0 :(得分:0)

不幸的是,geo_distance查询不允许使用脚本来指定动态距离。但是,您可以做的是在terms字段上使用action_zone聚合,以便在特定操作区域内存储所有文档。

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "is_active": True
          }
        }
      ],
      "filter": {
        "geo_distance": {
          "distance": "200km",
          "pin.location": {
            "lat": 40,
            "lon": -70
          }
        }
      }
    }
  },
  "aggs": {
    "zones": {
      "terms": {
        "field": "action_zone"
      }
    }
  }
}

否则,您还可以在range字段上使用action_zone聚合,并指定一些特定距离:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "is_active": "True"
          }
        }
      ],
      "filter": {
        "geo_distance": {
          "distance": "200km",
          "pin.location": {
            "lat": 40,
            "lon": -70
          }
        }
      }
    }
  },
  "aggs": {
    "zones": {
      "range": {
        "field": "action_zone",
        "ranges": [
          {
            "to": 50
          },
          {
            "from": 50,
            "to": 100
          },
          {
            "from": 100,
            "to": 150
          },
          {
            "from": 150
          }
        ]
      }
    }
  }
}

答案 1 :(得分:0)

我使用脚本找到了解决方案:D谢谢!

{
"query": {
    "bool" : {
        "must" :
            [{
                "term": {
                    "is_active": True
                }
            },{
                "script" : {
                    "script" : {
                        "params": {
                            "lat": 40.8,
                            "lon": -70.1
                        },
                        "source": "doc['location'].arcDistance(params.lat, params.lon) / 1000 < doc['action_zone'].value",
                        "lang": "painless"
                    }
                }
            }]
        }
    }
}

}

Doc:https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-script-query.html