【问题标题】:Mongoose.js - different population than usualMongoose.js - 与平时不同的人群
【发布时间】:2016-07-15 21:37:06
【问题描述】:

我有以下来自“main”集合的简化文档:

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

这是我的“菜单”集合中的简化文档:

{
    _id: 5,
    menuItems: [an array of elements here],
    menuProperties: {an object here}
}

是否可以使用 mongoose.js 将“菜单”文档填充到“主”文档中,从而产生以下模型对象:

{
    _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}
            }
}

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

【问题讨论】:

    标签: mongodb mongoose mongoose-populate


    【解决方案1】:

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

    //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)
        })
    
    })
    

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

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

    【讨论】:

    • 感谢您的努力,但我需要将 menu 文档填充到 main 文档中。我还需要menu 的属性与`main' 的属性处于同一级别
    • 以上代码遍历所有菜单文档。对于每个菜单文档,它会找到匹配的主文档。然后它使用菜单文档信息填充主文档。这不是你想要的吗?
    【解决方案2】:

    一种方法是从填充结果中删除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' } } ]
    

    【讨论】:

    • 感谢您的回答,我认为您可以在.exec() 调用之前添加.lean() 而不是使用.lean()
    猜你喜欢
    • 2015-09-24
    • 2015-06-06
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2013-06-15
    • 2018-09-12
    相关资源
    最近更新 更多