ElasticSearch,过滤经度或纬度应大于0的位置
ElasticSearch, filter locations where either longitude or latitude should be larger than 0
我试图实现的是 geo_bounds 的聚合。然而,在测试数据库中,我们得到了一些奇怪的值,其中位置可能是负数(这并不奇怪),这在这种情况下没有意义。
对于某些查询,这可能会导致边界框覆盖我们不期望的另一个国家/地区。
我想过滤经度或纬度必须大于 0 的 geo_bounds 聚合。
我知道 https://www.elastic.co/guide/en/elasticsearch/reference/1.6/search-aggregations-bucket-filter-aggregation.html 中指定了聚合过滤器,但我真的不确定如何范围检查经度或纬度。
在我们的索引模型中,我们得到了一个结构,其中有一个包含经度和纬度的位置对象。
由于负值对位置有效,因此它们被 ES 视为有效。因此,这里有 2 个选项:在索引期间验证数据(IMO 更好,但在您的情况下似乎为时已晚)或在查询中过滤掉具有负位置值的点。
即时过滤的问题是 ES 实际上只能过滤 4 filters 的地理点。而且这种过滤器在性能方面并不便宜。您可以根据需要使用 geo_bounding_box
,如下所示:
索引:
PUT so/_mapping/t1
{
"t1": {
"properties": {
"pin": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
}
POST so/t1
{
"pin": {
"location": {
"lat": 10.1,
"lon": 9.9
}
}
}
POST so/t1
{
"pin": {
"location": {
"lat": 20.1,
"lon": 99.9
}
}
}
POST so/t1
{
"pin": {
"location": {
"lat": -10.1,
"lon": -9.9
}
}
}
查询:
GET so/t1/_search?search_type=count
{
"aggs": {
"plain": {
"geo_bounds": {
"field": "pin.location"
}
},
"positive": {
"filter": {
"geo_bounding_box": {
"pin.location": {
"top_left": {
"lat": 90,
"lon": 0
},
"bottom_right": {
"lat": 0,
"lon": 180
}
}
}
},
"aggs": {
"bounds": {
"geo_bounds": {
"field": "pin.location"
}
}
}
}
}
}
结果:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 0,
"hits": []
},
"aggregations": {
"positive": {
"doc_count": 2,
"bounds": {
"bounds": {
"top_left": {
"lat": 20.1,
"lon": 9.9
},
"bottom_right": {
"lat": 10.1,
"lon": 99.9
}
}
}
},
"plain": {
"bounds": {
"top_left": {
"lat": 20.1,
"lon": -9.9
},
"bottom_right": {
"lat": -10.1,
"lon": 99.9
}
}
}
}
}
我试图实现的是 geo_bounds 的聚合。然而,在测试数据库中,我们得到了一些奇怪的值,其中位置可能是负数(这并不奇怪),这在这种情况下没有意义。
对于某些查询,这可能会导致边界框覆盖我们不期望的另一个国家/地区。
我想过滤经度或纬度必须大于 0 的 geo_bounds 聚合。
我知道 https://www.elastic.co/guide/en/elasticsearch/reference/1.6/search-aggregations-bucket-filter-aggregation.html 中指定了聚合过滤器,但我真的不确定如何范围检查经度或纬度。
在我们的索引模型中,我们得到了一个结构,其中有一个包含经度和纬度的位置对象。
由于负值对位置有效,因此它们被 ES 视为有效。因此,这里有 2 个选项:在索引期间验证数据(IMO 更好,但在您的情况下似乎为时已晚)或在查询中过滤掉具有负位置值的点。
即时过滤的问题是 ES 实际上只能过滤 4 filters 的地理点。而且这种过滤器在性能方面并不便宜。您可以根据需要使用 geo_bounding_box
,如下所示:
索引:
PUT so/_mapping/t1
{
"t1": {
"properties": {
"pin": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
}
POST so/t1
{
"pin": {
"location": {
"lat": 10.1,
"lon": 9.9
}
}
}
POST so/t1
{
"pin": {
"location": {
"lat": 20.1,
"lon": 99.9
}
}
}
POST so/t1
{
"pin": {
"location": {
"lat": -10.1,
"lon": -9.9
}
}
}
查询:
GET so/t1/_search?search_type=count
{
"aggs": {
"plain": {
"geo_bounds": {
"field": "pin.location"
}
},
"positive": {
"filter": {
"geo_bounding_box": {
"pin.location": {
"top_left": {
"lat": 90,
"lon": 0
},
"bottom_right": {
"lat": 0,
"lon": 180
}
}
}
},
"aggs": {
"bounds": {
"geo_bounds": {
"field": "pin.location"
}
}
}
}
}
}
结果:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 0,
"hits": []
},
"aggregations": {
"positive": {
"doc_count": 2,
"bounds": {
"bounds": {
"top_left": {
"lat": 20.1,
"lon": 9.9
},
"bottom_right": {
"lat": 10.1,
"lon": 99.9
}
}
}
},
"plain": {
"bounds": {
"top_left": {
"lat": 20.1,
"lon": -9.9
},
"bottom_right": {
"lat": -10.1,
"lon": 99.9
}
}
}
}
}