以下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 聚合中使用查找,我想在 personaddress 集合中嵌入 places 集合
Using lookup in mongodb aggregation, I want to embed places collection in personaddress collection
我尝试过使用
Aggregation aggregation = newAggregation(lookup("places", "address.location.place._id", "_id", "myplaces"), unwind("myplaces")); AggregationResults<OutputDocument> aggResults = mongoTemplate.aggregate(aggregation, PersonAddressDocument.class, OutputDocument.class);谁能帮帮我?
推荐答案由于你有嵌套数组,你需要应用 $unwind 运算符,以便在使用 $lookup 管道(除非您已经在聚合操作中将它们展平):
Since you have nested arrays, you need to apply the $unwind operator first in order to denormalise the embedded documents before using the $lookup pipeline (unless you have already flattened them in your aggregation operation):
db.personaddress.aggregate([ { "$unwind": "$address" }, { "$unwind": "$address.location" }, { "$lookup": { "from": "places", "localField": "address.location.place._id", "foreignField": "_id", "as": "address.location.place", } } ])然后可以实现为(未经测试):
which can then be implemented as (untested):
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<OutputDocument> aggResults = mongoTemplate.aggregate( agg, PersonAddressDocument.class, OutputDocument.class );如果您的 Spring Data 版本不支持此功能,解决方法是实现 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 操作:
Then implement the $lookup operation as a DBObject in the aggregation pipeline:
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<OutputDocument> aggResults = mongoTemplate.aggregate( agg, PersonAddressDocument.class, OutputDocument.class );更多推荐
在 mongodb 聚合中查找
发布评论