mongoose更新嵌入式文档 - 更改不反映

时间:2012-07-26 19:19:41

标签: node.js mongodb mongoose

我很擅长将Node.js和MongoDB与Mongoose一起使用。 目前,我正面临着一个相当烦人的问题,我确信有一个比我迄今为止提出的解决方案更好的解决方案!

问题是,我找不到更新嵌入式文档的“好方法”。 这是我的情景:

  1. 创建列表容器
  2. 创建N个ListItems,并将它们添加到List-container
  3. 查找并更新ListItem X的值
  4. 这很容易直截了当,但我一直都不走运 - 简单,无论如何。

    这是我到目前为止所拥有的。这是两个解决方案,两者都有效,但两者都需要在某个时刻遍历ListItems,我真的很喜欢 NOT

    ShoppingListItem = new Schema({
      listID : ObjectId
     ,ingredient : [Ingredient]
     ,count : Number
    });
    
    ShoppingList = new Schema({
      name : String
     ,userID : ObjectId
     /* Embedded documents solution */
     ,items : [ShoppingListItem]
     /* No embedded documents solution */
     /*,items : [{
         ingredient : [Ingredient]
        ,count : Number
     }]*/
    });
    
    ShoppingList.methods.addItem = function addItem(newItem, cb){
      var __self = this;
      var _id = __self._id;
      /**
       *  Embedded documents solution (Need to both maintain the embedded document source PLUS manually update the actual embedded document)
       **/
      ShoppingListItem.findOne({'listID' : _id, 'ingredient.name' : newItem.ingredient.name}, function(err, item){
        if(!item){
          var item = new ShoppingListItem({
             listID : _id
            ,ingredient : [newItem.ingredient]
            ,count : newItem.count
          });
          item.save(function(err, saved){
            __self.items.push(saved);
            __self.save(cb);
          });
        }else{
          item.count += newItem.count;
          item.save(function(err, saved){
            //Iterate through all ListItems to update the embedded document to reflect the changed "source" document
            for(var i = 0; i < __self.items.length; ++i){
              if(__self.items[i]._id.equals(saved._id)){
                __self.items[i] = saved;
              }
            }
            __self.markModified('items');
            __self.save(cb);
          });
        }
      });
    
      /**
       * No embedded documents solution (Only need to maintain the internal objects)
       **/
     /*
      var existing = __self.items.filter(function(item){ return item.ingredient.name.equals == newItem.ingredient.name;});
      if(existing.length > 0){
        existing[0].count += newItem.count;
      }else{
        __self.items.push(newItem)
      }
      __self.markModified('items');
      __self.save(cb);
      */
    }
    

    在上面的两个解决方案中,我会说后者是更“优雅”的解决方案,因为它的代码最少。但我真的希望能够使用第一种方法,因为我会说,MongoDB的查询在查找文档方面要比过滤数组更快。我最后的想法是尝试利用Mongoose的DBRef功能,但我无法弄清楚如何在我的解决方案中应用它。

    所以,长问题简短: 有没有办法“链接”文档,而不是“嵌入副本”(这是我看到的嵌入式文档)?

    提前多多感谢!

    编辑:以上两种解决方案都有效 - 但我看不出它们在更大范围内效率非常高(例如列表中的1.000.000+项目)

0 个答案:

没有答案