地理空间$接近当前文档字段值

时间:2017-06-22 09:02:02

标签: mongodb mongodb-query aggregation-framework geospatial spring-mongodb

采取此查询:

{ 'location' : { '$near' : [x,y], '$maxDistance' : this.field } }

我想从当前评估文档中为$ maxDistance分配指定字段的值。那可能吗?

1 个答案:

答案 0 :(得分:3)

是的,这是可能的。您只需使用$geoNear即可。小心捕获并仔细阅读。

假设您的意图是存储诸如"travelDistance"之类的字段,以在文档上指明任何此类搜索必须在“提供”距离查询点有效的距离内。然后我们只使用$redact查询和评估条件:

db.collection.aggregate([
  { "$geoNear": {
    "near": { 
      "type": "Point",
      "coordinates": [x,y]
    },
    "spherical": true,
    "distanceField": "distance"
  }},
  { "$redact": {
    "$cond": {
      "if": { "$lte": [ "$distance", "$travelDistance" ] },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

唯一的问题是$geoNear就像$near一样,只会首先返回一定数量的文档“附近”。您可以使用选项对其进行调整,但与通用查询表单不同,这基本上可以保证最终返回的结果将小于指定的“最近”数字。

只要你知道这一点,那就完全有效了。

事实上,这是处理在半径范围内“接近”的资格的一般方法。

根据您存储坐标的方式,还要注意“距离”。作为传统坐标对,距离将以弧度为单位,您可能需要将数学转换为公里或英里。

如果使用GeoJSON,则距离始终以米为单位,作为标准格式。

所有数学注释都在文档中。

  

N.B 请仔细阅读$geoNear文档。 "spherical"索引需要"2dsphere"等选项,例如您应该拥有真实世界坐标。此外,可能还需要应用"limit"来增加超过默认的100个文档结果,以便进一步修剪。

正如评论中提到的春天mongo,那么基本上就是这样做了:

Aggregation aggregation = newAggregation(
    new AggregationOperation() {
      @Override
      public DBObject toDBObject(AggregationOperationContext context) {
        return new BasicDBObject("$geoNear",
          new BasicDBObject(
            "near", new BasicDBObject(
              "type","Point")
              .append("coordinates", Arrays.asList(20,30))
            )
            .append("spherical",true)
            .append("distanceField","distance")
          );
        }
    },
    new AggregationOperation() {
      @Override
      public DBObject toDBObject(AggregationOperationContext context) {
        return new BasicDBObject("$redact",
          new BasicDBObject(
            "$cond", Arrays.asList(
               new BasicDBObject("$lte", Arrays.asList("$distance", "$travelDistance")),
               "$$KEEP",
               "$$PRUNE"
             )
          )
       );
     }
    }
);