由于无法动态设置每个文档的距离,因此您将无法使用普通查询执行此操作。从MongoDB 2.4开始,您可以使用聚合框架来完成此任务,因为它们已将geoNear运算符添加到流水线开始处。
第一阶段将是与geonear命令非常相似的geoNear。因此,我们还将获得从指定点(10,10)到文档的距离。
第二阶段我们将需要使用项目操作员来添加maximumDistance字段和计算出的地理距离之间的差异。
最后,我们匹配那些有正值的文件((最大距离)> 0)。
这里是使用Asynchronous Java Driver的帮助类的流水线。
package example;
import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
import static com.allanbank.mongodb.builder.QueryBuilder.where;
import static com.allanbank.mongodb.builder.expression.Expressions.field;
import static com.allanbank.mongodb.builder.expression.Expressions.set;
import static com.allanbank.mongodb.builder.expression.Expressions.subtract;
import com.allanbank.mongodb.bson.element.ArrayElement;
import com.allanbank.mongodb.builder.Aggregate;
import com.allanbank.mongodb.builder.AggregationGeoNear;
import com.allanbank.mongodb.builder.GeoJson;
public class AggregateGeoNear {
public static void main(String[] args) {
Aggregate aggregate = Aggregate
.builder()
.geoNear(
AggregationGeoNear.builder()
.location(GeoJson.p(10, 10))
.distanceField("distance"))
.project(
include("name", "location", "maximumDistance"),
set("delta",
subtract(field("maximumDistance"),
field("distance"))))
.match(where("delta").greaterThanOrEqualTo(0)).build();
System.out
.println(new ArrayElement("pipeline", aggregate.getPipeline()));
}
}
这里是创建管道:
pipeline : [
{
'$geoNear' : {
near : [
10,
10
],
distanceField : 'distance',
spherical : false,
uniqueDocs : true
}
},
{
'$project' : {
name : 1,
location : 1,
maximumDistance : 1,
delta : {
'$subtract' : [
'$maximumDistance',
'$distance'
]
}
}
},
{
'$match' : {
delta : { '$gte' : 0 }
}
}
]
HTH - 罗布。
P.S.上面的建设者正在使用该驱动程序的1.2.0版本的预发行版本。代码正在通过构建矩阵输入,并将于2013年3月22日星期五发布。
非常感谢这个非常详细的答案。听起来和我需要的完全一样,我现在试着弄清楚我是否可以用Spring Data - MongoDb做同样的事情 – 2013-03-21 04:06:09