我有一份教育机构文件,如下所示:
{ 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);
然而它返回了我想要展开的所有地址,我只需要从某个点附近的地址
答案 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