如何从MongoDB中的两个集合中加入数据?

时间:2022-03-20 04:51:58

I'am developing some application on MEAN.js boilerplate and I've got one problem which I'm not able to solve by myself :( I've got a following database scheme:

我在MEAN.js样板上开发了一些应用程序,我遇到了一个我自己无法解决的问题:(我有一个以下的数据库方案:

var UserSchema = new Schema({
    profession: {
        type: Schema.ObjectId,
        ref: 'Profession'
    },
    game: {
        type: Schema.ObjectId,
        ref: 'Game'
    }
};

var ProfessionSchema = new Schema({
    assignedTaskCategories: [{
        type: Schema.ObjectId,
        ref: 'TaskCategory'
    }]
});

var TaskCategorySchema = new Schema({
    professions: [{
        type: Schema.ObjectId,
        ref: 'Profession'
    }],
    assignedToGame: {
        type: Schema.ObjectId,
        ref: 'Game'
    }
});

var TaskSchema = new Schema({
    game: {
        type: Schema.ObjectId,
        ref: 'Game'
    },
    inCategories: [{
        type: Schema.ObjectId,
        ref: 'TaskCategory'
    }]
});

Now I would like to get all Tasks, which have got some element in inCategories same as User's profession taskCategories array. I've tried this, but it returns nothing

现在我想得到所有的任务,其中inCategories中的一些元素与User的职业taskCategories数组相同。我试过这个,但它什么都没有

Profession.find({ _id: req.user.profession }).exec(function(err, userCategories) {
        if(err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            Task.find({ game: req.user.game, inCategories: userCategories.assignedTaskCategories}).exec(function(err, tasks) {
                if(err) {
                    return res.status(400).sed({
                        message: errorHandler.getErrorMessage(err)
                    });
                } else {
                    res.json(tasks);
                }
            });
        }
    });

Could anyone help me with this? :) If my approach is bad, please tell me the right way how can I solve it :)

任何人都可以帮我这个吗? :)如果我的方法不好,请告诉我正确的方法如何解决它:)

EDIT

We cannot use $setEquals, because the array are not same, consider following example:

我们不能使用$ setEquals,因为数组不相同,请考虑以下示例:

Profession programmer is able to solve following task categories: Programming, Presentation, Wash dishes

专业程序员能够解决以下任务类别:编程,演示,洗碗

Profession secretary is able to solve following task categories: Presentation, Wash dishes

专业秘书能够解决以下任务类别:演示,洗碗

Then we will create a task, which is assigned to category: Wash dishes, so the professions assignedCategories arrays are bigger, not equal to task's inCategories array.

然后我们将创建一个任务,分配到类别:洗碗,所以职业分配的类别数组更大,不等于任务的inCategories数组。

1 个解决方案

#1


Try using the aggregation framework where you employ the $setEquals operator to compare the arrays. In the following pipeline, the operator determines if the Tasks' inCategories array and the assignedTaskCategories array contain the same elements:

尝试使用聚合框架,您可以使用$ setEquals运算符来比较数组。在以下管道中,操作员确定Tasks的inCategories数组和assignedTaskCategories数组是否包含相同的元素:

Profession.find({ _id: req.user.profession }).exec(function(err, userCategories) {
    if(err) {
        return res.status(400).send({
            message: errorHandler.getErrorMessage(err)
        });
    } else {
        var pipeline = [
            {
                "$match": { "game": req.user.game }
            },
            {
                "$project": { 
                    "game": 1, 
                    "inCategories": 1, 
                    "sameElements": { 
                        "$setEquals": [ "$inCategories", userCategories[0].assignedTaskCategories ] 
                    }
                }
            },
            {
                "$match": { "sameElements": true }
            }
        ];
        Task.aggregate(pipeline)
            .exec(function (err, tasks){
                if(err) {
                    return res.status(400).sed({
                        message: errorHandler.getErrorMessage(err)
                    });
                } else {
                    res.json(tasks);
                }
        });

    }
});

#1


Try using the aggregation framework where you employ the $setEquals operator to compare the arrays. In the following pipeline, the operator determines if the Tasks' inCategories array and the assignedTaskCategories array contain the same elements:

尝试使用聚合框架,您可以使用$ setEquals运算符来比较数组。在以下管道中,操作员确定Tasks的inCategories数组和assignedTaskCategories数组是否包含相同的元素:

Profession.find({ _id: req.user.profession }).exec(function(err, userCategories) {
    if(err) {
        return res.status(400).send({
            message: errorHandler.getErrorMessage(err)
        });
    } else {
        var pipeline = [
            {
                "$match": { "game": req.user.game }
            },
            {
                "$project": { 
                    "game": 1, 
                    "inCategories": 1, 
                    "sameElements": { 
                        "$setEquals": [ "$inCategories", userCategories[0].assignedTaskCategories ] 
                    }
                }
            },
            {
                "$match": { "sameElements": true }
            }
        ];
        Task.aggregate(pipeline)
            .exec(function (err, tasks){
                if(err) {
                    return res.status(400).sed({
                        message: errorHandler.getErrorMessage(err)
                    });
                } else {
                    res.json(tasks);
                }
        });

    }
});