$ near unwind mongodb geospatial

时间:2013-08-26 19:46:38

标签: mongodb geolocation geospatial mongodb-java

我有一份教育机构文件,如下所示:

{ name: ..., addresses: [{state: ..., locs: []}, ...], courses: [...] }

locs是我的地理空间点的位置。

要执行$near命令,我需要$unwind个地址,因为我可以在很多方面拥有教育机构。

我目前的方法如下:

public BasicDBList findByCoordinates(double latitude, double longitude){

    BasicDBObject cmdBody = new BasicDBObject("aggregate", "EducationalInstitution");

    List<BasicDBObject> pipeline = new ArrayList<BasicDBObject>();

    BasicDBObject projectParams = new BasicDBObject();
    projectParams.put("name", 1);
    projectParams.put("addresses.state", 1);
    projectParams.put("addresses.locs", 1);
    projectParams.put("courses", 1);

    BasicDBObject geoParams = new BasicDBObject();
    geoParams.put("$near", new double[] { latitude, longitude });
    geoParams.put("$maxDistance", 50/111.12);

    pipeline.add(new BasicDBObject("$project", projectParams));
    pipeline.add(new BasicDBObject("$unwind", "$addresses"));

    cmdBody.put("pipeline", pipeline);
    cmdBody.put("$addresses.locs", geoParams);

    return (BasicDBList) getDatastore().getDB().command(cmdBody).get("result");
}

我尝试了从morphia

附近的方法
createQuery().field("addresses.locs").near(latitude, longitude, 50/111.12);

然而它返回了我想要展开的所有地址,我只需要从某个点附近的地址

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。首先,我尝试使用$ match和$ near,但是没有成功。

然后我阅读了关于$ geoNear聚合并尝试将put作为我的管道的最后一个参数,但是,根据MongoDB页面:“你只能使用$ geoNear作为管道的第一阶段。”

我对我需要的$ unwind感到怀疑,但是,我发现了一个参数可以帮助我进行数组本地化。

我的shell代码:

db.EducationalInstitution.aggregate( {$geoNear: {near: [-15.795758,-47.892312], maxDistance: 50/111.12, distanceField: "addresses.calculated", includeLocs: "addresses.locs", niqueDocs: true}}, {$project: {"name": 1, "addresses.state": 1, "addresses.locs": 1}} );

我的Java代码:

public BasicDBList findByCoordinates(double longitude, double latitude){

    BasicDBObject cmdBody = new BasicDBObject("aggregate", "EducationalInstitution");

    List<BasicDBObject> pipeline = new ArrayList<BasicDBObject>();

    BasicDBObject geoNearParams = new BasicDBObject();
    geoNearParams.put("near", new double[] {longitude, latitude,});
    geoNearParams.put("maxDistance", 50/111.12);
    geoNearParams.put("distanceField", "addresses.calculated");
    geoNearParams.put("includeLocs", "addresses.locs");
    geoNearParams.put("niqueDocs", true);

    BasicDBObject projectParams = new BasicDBObject();
    projectParams.put("name", 1);
    projectParams.put("addresses.state", 1);
    projectParams.put("addresses.locs", 1);
    projectParams.put("courses", 1);

    pipeline.add(new BasicDBObject("$geoNear", geoNearParams));
    pipeline.add(new BasicDBObject("$project", projectParams));

    cmdBody.put("pipeline", pipeline); 

    if( !getDatastore().getDB().command(cmdBody).ok() ){

        throw new MongoException(getDatastore().getDB().command(cmdBody).getErrorMessage());
    }

    return (BasicDBList) getDatastore().getDB().command(cmdBody).get("result");
}

BasicDBObject cmdBody = new BasicDBObject("aggregate", "EducationalInstitution"); List<BasicDBObject> pipeline = new ArrayList<BasicDBObject>(); BasicDBObject geoNearParams = new BasicDBObject(); geoNearParams.put("near", new double[] {longitude, latitude,}); geoNearParams.put("maxDistance", 50/111.12); geoNearParams.put("distanceField", "addresses.calculated"); geoNearParams.put("includeLocs", "addresses.locs"); geoNearParams.put("niqueDocs", true); BasicDBObject projectParams = new BasicDBObject(); projectParams.put("name", 1); projectParams.put("addresses.state", 1); projectParams.put("addresses.locs", 1); projectParams.put("courses", 1); pipeline.add(new BasicDBObject("$geoNear", geoNearParams)); pipeline.add(new BasicDBObject("$project", projectParams)); cmdBody.put("pipeline", pipeline); if( !getDatastore().getDB().command(cmdBody).ok() ){ throw new MongoException(getDatastore().getDB().command(cmdBody).getErrorMessage()); } return (BasicDBList) getDatastore().getDB().command(cmdBody).get("result"); }

THX