首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有可变距离的MongoDb近/地查询

具有可变距离的MongoDb近/地查询
EN

Stack Overflow用户
提问于 2013-03-20 22:31:33
回答 2查看 2.5K关注 0票数 0

我想要执行一个查询,其中距离是一个来自集合的动态字段。

集合中的条目示例:

代码语言:javascript
复制
{
  name:'myName',
  location: {lat:10, lng:20},
  maximumDistance: 10
}
{
  name:'myName2',
  location: {lat:20, lng:20},
  maximumDistance: 100
}

我的目标是从这个集合中检索所有元素,其中这个位置接近一个给定的位置,比方说(10,10),但是计算的距离小于这个maximumDistance字段。

我可以将maxDistance设置为一个常量值(足够高到可以检索我想要的所有元素),然后在我的java代码中执行过滤器,但是我更愿意在查询上这样做,这可能过于面向SQL了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-21 03:20:38

由于无法动态地设置每个文档的距离,因此无法使用普通查询完成此操作。从MongoDB 2.4开始,您可以使用聚合框架来实现这一点,因为它们已经将geoNear操作符添加到管道的启动过程中。

第一个阶段是geoNear,它非常类似geonear命令。因此,我们还将得到从指定的点(10,10)到文档的距离。

第二阶段,我们需要使用项目操作符来区分maximumDistance字段和计算的geoNear距离之间的差异。

最后,我们匹配具有正增量((最大距离)> 0)的文档。

下面是使用异步Java驱动程序的助手类的管道。

代码语言:javascript
复制
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()));
    }
}

下面是创建的管道:

代码语言:javascript
复制
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日星期五发布。

票数 4
EN

Stack Overflow用户

发布于 2014-05-26 13:02:46

关于如何使用Spring数据解决它,我已经通过构建一个新的GeoNearOperation实现来解决它,因为在投影中必须包括maxDistance字段名:

代码语言:javascript
复制
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);
}

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15536064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档