我想要执行一个查询,其中距离是一个来自集合的动态字段。
集合中的条目示例:
{
name:'myName',
location: {lat:10, lng:20},
maximumDistance: 10
}
{
name:'myName2',
location: {lat:20, lng:20},
maximumDistance: 100
}我的目标是从这个集合中检索所有元素,其中这个位置接近一个给定的位置,比方说(10,10),但是计算的距离小于这个maximumDistance字段。
我可以将maxDistance设置为一个常量值(足够高到可以检索我想要的所有元素),然后在我的java代码中执行过滤器,但是我更愿意在查询上这样做,这可能过于面向SQL了。
发布于 2013-03-21 03:20:38
由于无法动态地设置每个文档的距离,因此无法使用普通查询完成此操作。从MongoDB 2.4开始,您可以使用聚合框架来实现这一点,因为它们已经将geoNear操作符添加到管道的启动过程中。
第一个阶段是geoNear,它非常类似geonear命令。因此,我们还将得到从指定的点(10,10)到文档的距离。
第二阶段,我们需要使用项目操作符来区分maximumDistance字段和计算的geoNear距离之间的差异。
最后,我们匹配具有正增量((最大距离)> 0)的文档。
下面是使用异步Java驱动程序的助手类的管道。
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 }
}
}
]嘿-罗伯。
上面的构建程序使用的是1.2.0版本的驱动程序的预发布版。当我键入时,代码将通过构建矩阵,并将在2013年3月22日星期五发布。
发布于 2014-05-26 13:02:46
关于如何使用Spring数据解决它,我已经通过构建一个新的GeoNearOperation实现来解决它,因为在投影中必须包括maxDistance字段名:
public class GeoNearOperation2 implements AggregationOperation {
private NearQuery nearQuery;
public GeoNearOperation2(NearQuery nearQuery) {
this.nearQuery = nearQuery;
}
public DBObject toDBObject(AggregationOperationContext context) {
DBObject dbObject = context.getMappedObject(nearQuery.toDBObject());
dbObject.put("distanceField", "distance");
return new BasicDBObject("$geoNear",dbObject);
}
}https://stackoverflow.com/questions/15536064
复制相似问题