我有以下结构。我想阻止使用相同的属性推送文档。
E.g。基本上,我首先找到用户对象。如果我有另一个视频(已经在里面),它将不会被推入。尝试使用$ addToSet,但失败了。
我正在使用Mongoose。
这是我的模型结构:
var User = mongoose.model('User', {
oauthID: Number,
name: String,
username: String,
email: String,
location: String,
birthday: String,
joindate: Date,
pvideos: Array
});
这是我推送到Mongo的代码
exports.pinkvideo = function(req, res) {
var vid = req.body.vid;
var oauthid = req.body.oauthid;
var User = require('../models/user.js');
var user = User.findOne({
oauthID: oauthid
}, function(err, obj) {
if (!err && obj != null) {
obj.pvideos.push({
vid: vid
});
obj.save(function(err) {
res.json({
status: 'success'
});
});
}
});
};
答案 0 :(得分:2)
您需要.update()
方法,而不是在进行更改后检索文档并使用.save()
。
这不仅可以让您访问上面提到的$addToSet
运算符,而且它的目的是避免数组中的重复,因为您只是将更改发送到数据库而不是整个数据库文件来回:
User.update(
{ oauthID: oauthid },
{ "$addToSet": { "pVideos": vid } },
function( err, numAffected ) {
// check error
res.json({ status: "success" })
}
)
唯一可能的问题是它取决于你实际推入阵列并期望它是唯一的。所以如果你的数组看起来像这样:
[ { "name": "A", "value": 1 } ]
你用这样的数组元素发送和更新:
{ "name": "A", "value": 2 }
然后,该文件不会被视为纯粹存在于“名称”中“A”的值,并且会添加一个额外的文档而不是仅替换现有文档。
因此,您需要注意您的意图,如果这是您正在寻找的那种逻辑,那么您需要找到该文档并测试现有数组条目以了解您想要的条件。
但对于您根本不想添加明确副本的基本情况,如图所示$addToSet
就是您想要的。