在mongodb聚合中查找

以下bson是personaddress集合:

 { "id" : "123456", "name" : "foo", "address" : [ { "local" : "yes", "location" : [ { "place" : { "_id":"VZG", }, "place_lat" : "18", "place_lan" : "83", }, { "place" : { "name" : "kerala", "district" : "palakkad", "pincode" : "5203689", }, "place_lat" : "18", "place_lan" : "83", } ] } ] } 

我有另一个places集合:

  { "_id":"VZG", "name" : "vizag", "district" : "Visakhaptanam, "pincode" : "568923", } 

在mongodb聚合中使用lookup,我想在personaddress集合中嵌入places集合

我试过用

 Aggregation aggregation = newAggregation(lookup("places", "address.location.place._id", "_id", "myplaces"), unwind("myplaces")); AggregationResults aggResults = mongoTemplate.aggregate(aggregation, PersonAddressDocument.class, OutputDocument.class); 

谁能帮我?

由于您具有嵌套数组,因此在使用$lookup管道之前,需要首先应用$unwind运算符以使嵌入文档非规范化(除非您已在聚合操作中将它们展平):

 db.personaddress.aggregate([ { "$unwind": "$address" }, { "$unwind": "$address.location" }, { "$lookup": { "from": "places", "localField": "address.location.place._id", "foreignField": "_id", "as": "address.location.place", } } ]) 

然后可以实现为(未经测试):

 LookupOperation lookupOperation = LookupOperation.newLookup() .from("places") .localField("address.location.place._id") .foreignField("_id") .as("address.location.place"); Aggregation agg = newAggregation( unwind("address"), unwind("address.location"), lookupOperation ); AggregationResults aggResults = mongoTemplate.aggregate( agg, PersonAddressDocument.class, OutputDocument.class ); 

如果您的Spring Data版本不支持此function,则解决方法是实现AggregationOperation接口以接收DBObject

 public class CustomGroupOperation implements AggregationOperation { private DBObject operation; public CustomGroupOperation (DBObject operation) { this.operation = operation; } @Override public DBObject toDBObject(AggregationOperationContext context) { return context.getMappedObject(operation); } } 

然后在聚合管道中将$lookup操作实现为DBObject:

 DBObject lookupOperation = (DBObject)new BasicDBObject( "$lookup", new BasicDBObject("from", "places") .append("localField", "address.location.place._id") .append("foreignField", "_id") .append("as", "address.location.place") ); 

您可以将其用作:

 Aggregation agg = newAggregation( unwind("address"), unwind("address.location"), lookupOperation ); AggregationResults aggResults = mongoTemplate.aggregate( agg, PersonAddressDocument.class, OutputDocument.class );