ElasticSearch,过滤经度或纬度应大于0

时间:2015-08-03 07:35:46

标签: elasticsearch geolocation aggregate

我尝试实现的是geo_bounds的聚合。但是,在测试数据库中,我们得到了一些奇怪的值,其中位置可能是负的(这不是每个人说的很奇怪),在这种情况下没有意义。

对于某些查询,这可能会导致包含另一个我们不期望的国家/地区的边界框。

我想过滤经度或纬度必须大于0的geo_bounds聚合。

我知道有一个聚合过滤器,如https://www.elastic.co/guide/en/elasticsearch/reference/1.6/search-aggregations-bucket-filter-aggregation.html所述,但我真的不确定如何检查经度或纬度。

在我们的索引模型中,我们得到了一个结构,其中我们有一个包含lon和lat的位置对象。

1 个答案:

答案 0 :(得分:1)

由于负值对于位置有效,因此ES将其视为有效。因此,这里有两个选项:在索引期间验证数据(方式更好的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
            }
         }
      }
   }
}