如何防止在Mongodb中推送具有相同属性的文档

时间:2014-05-30 15:18:39

标签: node.js mongodb mongoose mongodb-query

我有以下结构。我想阻止使用相同的属性推送文档。

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'
            });
        });

    }
});

};

1 个答案:

答案 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就是您想要的。