采取此查询:
{ 'location' : { '$near' : [x,y], '$maxDistance' : this.field } }
我想从当前评估文档中为$ maxDistance分配指定字段的值。那可能吗?
答案 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"
)
)
);
}
}
);