Mongoose.js - 与平时不同的人口

Mongoose.js - different population than usual

我有以下来自 collection "main" 的简化文档:

{
    _id: 120,
    name: "Main1",
    prop1: "val",
    menuId: 5
}

这是我的 "menu" collection:

的简化文档
{
    _id: 5,
    menuItems: [an array of elements here],
    menuProperties: {an object here}
}

是否可以使用 mongoose.js 将 "menu" 文档填充到 "main" 文档中,从而产生以下模型 object:

{
    _id: 120,
    name: "Main1",
    prop1: "val",
    menuItems: [an array of elements here],
    menuProperties: {an object here}
}

我现在能做到的是:

{
    _id: 120,
    name: "Main1",
    prop1: "val",
    menuId: {
               menuItems: [an array of elements here],
               menuProperties: {an object here}
            }
}

我没有添加这些方案,因为它们非常简单并且将包含 menuIdref。 谢谢!

有很多方法可以做到这一点。你总是可以做这样的事情(注意,你没有 post 你的模式所以我编了名字):

//get every document in menu collection
Menu.find({}).exec(function(err,all_menuItems){

    if (err) {throw err};

    //for all documents in them meny collection
    //find docuement in main collection and update

    all_menuItems.forEach(function(item){

        //wrapping in closure since doing forEach over async function
        function(){

            Main.findOne({_id:item._id}).exec(function(err,mainItem){

            if (err) {throw err};

            //set properties
            mainItem.menuItems = item.menuItems;
            menuItem.menuProperties = item.menuProperties;
            //save document
            Main.save(mainItem)

            })

        }(item)
    })

})

此外,mongoose 作为内置填充方法可用于执行此操作。您可以在此处找到该文档。 http://mongoosejs.com/docs/populate.html.

使用 populate 可能比循环一堆异步调用(或重写上面的代码以同步处理更新)更好。但是您可以处理对您的数据库最有意义的任何方式。

一种方法是从填充结果中删除 menuId,然后将 menuItemmenuProperties 添加到填充结果中。这是示例代码,

Main.find()
    .populate('menuId', 'menuItem menuProperties -_id', 'Menu')
    .exec(function(err, docs){
        if (err)
            console.log(err);
        else {
            var rets = [];
            docs.forEach(function(doc) {
                // converts the mongoose document into a plain javascript object
                doc = doc.toJSON();
                // add menuItem key
                if (doc.menuId && doc.menuId.menuItem) {
                    doc.menuItem = doc.menuId.menuItem;
                }
                // add menuProperties key
                if (doc.menuId && doc.menuId.menuProperties) {
                    doc.menuProperties = doc.menuId.menuProperties;

                    // remove the menuId object
                    delete doc.menuId
                }
                rets.push(doc);
            });

            console.log(rets);
        }
    });

使用架构测试

var MainSchema = new mongoose.Schema({
    name: String,
    prop1: String,
    menuId: Number
});

var MenuSchema = new mongoose.Schema({
    _id: Number,
    menuItem: [String],
    menuProperties: {k: String}
});

var Main = mongoose.model('Main', MainSchema);
var Menu = mongoose.model('Menu', MenuSchema);

结果是

[ { _id: 56fa39b4924d1254272ac3f1,
    name: 'main1',
    prop1: 'val',
    __v: 0,
    menuItem: [ 't1', 't2' ],
    menuProperties: { k: 'p1' } } ]