2016-03-28 8 views
1

У меня есть следующий упрощенный документ из коллекции «Основной»:Mongoose.js - разные популяции, чем обычно

{ 
    _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. Спасибо!

ответ

1

Один из способов - удалить menuId из результата популяции и добавить menuItem и menuProperties в список результатов. Вот коды образцов,

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

Test со схемой

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' } } ] 
+1

Спасибо за ответ, я думаю, что вместо использования 'doc.toJSON();' вы можете добавить '.lean()' перед '.exec()' вызовом – TBE

+0

@TBE, хороший улов .... – zangw

2

Существует много способов сделать это. Вы всегда можете сделать что-то вроде этого (обратите внимание, вы не отправляли свои схемы, так я сделал имена):

//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.

Использование заселения, вероятно, будет намного лучше, чем переключение на кучу асинхронных вызовов (или переписывание вышеуказанного кода для синхронного обновления обновлений). Но вы можете справиться с любым способом, который имеет наибольший смысл для вашего db.

+0

Спасибо за усилия, но мне нужно 'menu' документ заселяться в 'main'. Мне также нужно, чтобы свойства 'menu' находились на том же уровне, что и свойства' main '. – TBE

+0

. Вышеприведенный код выполняет итерацию через все документы меню. Для каждого документа меню он находит соответствующий основной документ. Затем он заполняет основной документ информацией о документе меню. Разве это не то, что вы хотите? – user2263572

Смежные вопросы