首页 > 解决方案 > $lookup 使用多个条件 mongodb java 聚合

问题描述

有以下 2 个集合:

用户集合

{
userId:user1,
creationTimeStamp:2019-11-05T08:15:30
status:active
},
{
userId:user2,
creationTimeStamp:2019-10-05T08:15:30
status:active
}

文件收集

{
userId:user1,
category:Development
published:true
},
{
userId:user2,
category:Development
published:false
}

我想加入这两个集合并过滤用户,以便那些属于开发类别并且不是在创建时间戳之间从活动用户发布的文档

如何编写 mongodb java 聚合以获得如下结果:

{
userId: user2,
status:active,
category:Development,
published:false
}

标签: mongodbaggregation-frameworklookup

解决方案


您还没有提到 User 集合中 userId 的重复项。

所以脚本是

[{
    $match: {
        category: "Development",
        published: false
    }
}, {
    $lookup: {
        from: 'user',
        localField: 'userId',
        foreignField: 'userId',
        as: 'joinUser'
    }
}, {
    $unwind: {
        path: "$joinUser",
        preserveNullAndEmptyArrays: true
    }
}, {
    $match: {
        "joinUser.status": "active"
    }
}, {
    $addFields: {
        "status": "$joinUser.status"
    }
}, {
    $project: {
        _id: 0,
        userId: 1,
        category: 1,
        published: 1,
        status: 1
    }
}]

还有java代码,

包括这些进口

import static org.springframework.data.mongodb.core.aggregation.Aggregation.match;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.lookup;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.unwind;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.project;

方法是,

public Object findAllwithVideos() {
    Aggregation aggregation=Aggregation.newAggregation(
        match(Criteria.where("category").is("Development").and("published").is(false)),
        lookup("user","userId","userId","joinUser"),
        unwind("joinUser",true),
        new AggregationOperation(){
            @Override
            public Document toDocument(AggregationOperationContext aggregationOperationContext){
                return new Document("$addFields",
                    new Document("status","$joinUser.status")
                );
            }
        },
        project("userId","category","published","status")
    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Document.class), Object.class);
}

推荐阅读