java - 在 mongodb 聚合中查找

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

下面的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);

谁能帮帮我?

最佳答案

因为你有嵌套数组,你需要应用 $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 的接口(interface):

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

关于java - 在 mongodb 聚合中查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41243746/

相关文章:

java - 如何从 JSON 对象的结果填充 ListView?

python - “串在一起”基于一组条件的pymongo查询

mongodb - 数据迁移后解析基于位置的查询不起作用

java - Spring 中对版本化实体的 ETag 支持

java - Spring——解耦与性能

java - Spring MVC RESTful 多 View - 404 未找到

java - 禁用外部库的 log4j 和 slf4j 初始化输出

java - 无法启动 Grizzly http 服务器

java - 应用程序获取网站响应

node.js - Elasticsearch 和 MongoDB 与 Nodejs