【问题标题】:lookup in mongodb aggregation在 mongodb 聚合中查找
【发布时间】:2017-05-05 18:05:12
【问题描述】:

以下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 聚合中使用查找,我想将 places 集合嵌入到 personaddress 集合中

我尝试过使用

Aggregation aggregation = newAggregation(lookup("places", "address.location.place._id", "_id", "myplaces"), unwind("myplaces"));

AggregationResults<OutputDocument> aggResults = mongoTemplate.aggregate(aggregation, PersonAddressDocument.class, OutputDocument.class);

谁能帮帮我?

【问题讨论】:

    标签: java mongodb spring-mvc mongodb-query aggregation-framework


    【解决方案1】:

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

    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<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:

    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
    );
    

    【讨论】:

    • 非常感谢
    【解决方案2】:
    db.productgroups.aggregate([
        // Unwind the source
        { "$unwind": "$products" },
        // Do the lookup matching
        { "$lookup": {
           "from": "products",
           "localField": "products",
           "foreignField": "_id",
           "as": "productObjects"
        }},
        // Unwind the result arrays ( likely one or none )
        { "$unwind": "$productObjects" },
        // Group back to arrays
        { "$group": {
            "_id": "$_id",
            "products": { "$push": "$productObjects" },
        }}
    ])
    

    【讨论】:

      猜你喜欢
      • 2017-09-22
      • 2022-01-03
      • 2020-04-14
      • 2017-11-08
      • 2020-06-29
      • 1970-01-01
      • 2019-01-17
      • 2022-06-16
      • 1970-01-01
      相关资源
      最近更新 更多