Как сделать $ setDifference в массиве и объекте, используя Mongo DB - PullRequest
0 голосов
/ 14 января 2019

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

Мне нужно взять UID из UserDetails , проверить с помощью UserProducts , затем взять UPID из UserProducts

Шаг 2

мы должны проверить это UPID сопоставленное с группами коллекцию или нет? members.regularStudent мы сопоставлены UPID

Шаг 3

Предположим, что UPID не сопоставлено означает, что я хочу напечатать UPID из UserProducts

Я пытался, но не смог завершить, пожалуйста, помогите мне с этим.

Ожидаемый результат:

["300"]

Примечание. Ожидаемый результат - ["300"], поскольку UserProducts имеет UPID 100 & 200, но Группы отображаются только для коллекции 100 & 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
        }
    }
])

Мой вывод

 {
    "members" : [
        "300",
        "100"
    ]
}

1 Ответ

0 голосов
/ 14 января 2019

Вам нужно исправить это второе объединение и получить все 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
        }
    }
])
...