保存唯一的数组元素MongoDB

时间:2016-05-15 21:10:39

标签: node.js mongodb mongoose

我正在尝试使用MongoDB保存一个独特的String元素数组,但由于某种原因,它允许我保存重复项。

我正在使用猫鼬。我的代码:

 schema = mongoose.Schema({
    "searchingId": { "type":  String,
        "unique": true,
        "index": true },
    "sharedTo" : {
        type: [String],
        unique: true,
        "trim":true
    }
}, {collection: 'myCollection'});

基本上,重点是保留用户发送电子邮件的电子邮件地址列表,并防止用户发送垃圾邮件。但是这个模式允许我将任何字符串推送到sharedTo数组并且.save(),无论是否存在重复项。如何防止这种情况发生?

编辑: 拉哈尔的答案对我的问题有所帮助,但不是很有意义。如果至少一个重复,我想阻止用户添加电子邮件。所以基本上$ addToSet将有助于唯一性,但不是我的问题。

3 个答案:

答案 0 :(得分:1)

您可以使用$ addToSet而不是$ push在“sharedTo”数组中添加电子邮件。 这不会添加重复元素(在您的情况下是电子邮件)。

通过提供唯一:true到整个数组字段不会检查数组元素的唯一性。

请查看$addToSet文档。

答案 1 :(得分:0)

您可以实现自己的静态函数,该函数将从架构类运行,以便为每个输入的电子邮件执行此操作

UserSchema.statics.findUseremail = function(useremail, suffix,
callback) {

var _this = this;
var possibleuseremail = useremail + (suffix || '');
_this.findOne({
    useremail: possibleuseremail
    }, function(err, userem) {
    if (!err) {
        if (!userem) {
            callback(findUseremail);
        } else {
        return _this.findUseremail(useremail, (suffix || 0) +
        1, callback);
        }
    } else {
    callback(null);
    }
});
};

答案 2 :(得分:0)

所以看起来我自己找到了解决方案,但感谢Lahar Shah的回答让我指向了正确的方向。而不是使用

Model.update(conditions, doc, [options], [callback])

我做了

  • 获取对象
  • 在检查重复项时,将每封电子邮件添加到 sharedTo 属性中。
  • 如果没有重复,则保存对象

代码:

var  length = emails.length;
for( var i = 0; i < length; i++ ) {
    var saved = doc.sharedTo.addToSet(emails[i]).length;
    if (saved != 1) {
        //status 409 - You have already sent email to user emails[i]
        return;
    }
}

doc[0].save(function(fail, success) {
    if(fail) {
        //error
    } else {
        //success return 200
    }
});