2

我对在 Mongoose 中使用 Node.js 和 MongoDB 还很陌生。目前,我面临一个相当烦人的问题,我确信有一个比我迄今为止提出的更好的解决方案!

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

  1. 创建一个列表容器
  2. 创建 N 个 ListItems,并将它们添加到 List-container
  3. 查找并更新 ListItem X 的值

这应该很简单,但我一直不走运 - 无论如何简单。

这是我到目前为止所拥有的。这是两个解决方案,两者都有效,但都需要在某些时候迭代ListItems,我真的不想这样做。

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

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

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

提前非常感谢!

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

4

0 回答 0