我很擅长将Node.js和MongoDB与Mongoose一起使用。 目前,我正面临着一个相当烦人的问题,我确信有一个比我迄今为止提出的解决方案更好的解决方案!
问题是,我找不到更新嵌入式文档的“好方法”。 这是我的情景:
这很容易直截了当,但我一直都不走运 - 简单,无论如何。
这是我到目前为止所拥有的。这是两个解决方案,两者都有效,但两者都需要在某个时刻遍历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+项目)