如何使用Mongo DB在数组和对象中设置$ setDifference

时间:2019-01-14 09:36:50

标签: mongodb mongodb-query aggregation-framework aggregate

UserDetails

{
    "_id" : "5c23536f807caa1bec00e79b",
    "UID" : "1",
    "name" : "A",
},
{
    "_id" : "5c23536f807caa1bec00e78b",
    "UID" : "2",
    "name" : "B",
},
{
"_id" : "5c23536f807caa1bec00e90",
"UID" : "3",
"name" : "C"
}

UserProducts

{
    "_id" : "5c23536f807caa1bec00e79c",
    "UPID" : "100",
    "UID" : "1",
    "status" : "A"
},
{
    "_id" : "5c23536f807caa1bec00e79c",
    "UPID" : "200",
    "UID" : "2",
    "status" : "A"
},
{
"_id" : "5c23536f807caa1bec00e52c",
"UPID" : "300",
"UID" : "3",
"status" : "A"
}

{
    "_id" : "5bb20d7556db6915846da55f",
    "members" : {
        "regularStudent" : [
            "200" // UPID
        ],
    }
},
{
"_id" : "5bb20d7556db69158468878",
"members" : {
    "regularStudent" : {
        "0" : "100" // UPID
    }
}
}

第1步

我必须从 UserDetails 中获取UID,并与 UserProducts 进行核对,然后从 UserProducts

中获取UPID

第2步

我们必须检查映射到 Groups 集合的UPID吗? members.regularStudent我们被映射为UPID

第3步

假设未映射 UPID ,这意味着我要从 UserProducts

中打印 UPID

我已经尝试过但无法完成,请帮助我。

  

预期输出:

["300"]

注意:预期输出为["300"],因为 UserProducts 具有UPID 100 & 200 Groups 集合仅映射了100和{{ 1}}。

我的代码

200
  

我的输出

var queryResult = db.UserDetails.aggregate(
{
$lookup: {
    from: "UserProducts",
    localField: "UID",
    foreignField: "UID",
    as: "userProduct"
    }
},
{ $unwind: "$userProduct" },
{ "$match": { "userProduct.status": "A" } },
{
    "$project": { "_id" : 0, "userProduct.UPID" : 1 }
},
{
    $group: {
        _id: null,
        userProductUPIDs: { $addToSet: "$userProduct.UPID" }
    }
});

let userProductUPIDs = queryResult.toArray()[0].userProductUPIDs;

db.Groups.aggregate([
    {
        $unwind: "$members.regularStudent"
    },
    {
        $group: {
            _id: null,
            UPIDs: { $addToSet: "$members.regularStudent" }
        }
    },
    {
        $project: {
            members: {
                $setDifference: [ userProductUPIDs , "$UPIDs" ]
            },
            _id : 0
        }
    }
])

1 个答案:

答案 0 :(得分:1)

您需要修复第二个聚合并将所有UPIDs作为数组。为此,您可以使用$cond并基于$type返回数组或使用$objectToArray来运行转换,请尝试:

db.Groups.aggregate([
    {
        $project: {
            students: {
                $cond: [ 
                    { $eq: [ { $type: "$members.regularStudent" }, "array" ] },
                    "$members.regularStudent",
                    { $map: { input: { "$objectToArray": "$members.regularStudent" }, as: "x", in: "$$x.v" } }
                ]
            }
        }
    },
    {
        $unwind: "$students"
    },
    {
        $group: {
            _id: null,
            UPIDs: { $addToSet: "$students" }
        }
    },
    {
        $project: {
            members: {
                $setDifference: [ userProductUPIDs , "$UPIDs" ]
            },
            _id : 0
        }
    }
])