我对在 Mongoose 中使用 Node.js 和 MongoDB 还很陌生。目前,我面临一个相当烦人的问题,我确信有一个比我迄今为止提出的更好的解决方案!
问题是,我找不到更新嵌入式文档的“好”方法。这是我的场景:
- 创建一个列表容器
- 创建 N 个 ListItems,并将它们添加到 List-container
- 查找并更新 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 多个项目)