2016-05-15 7 views
0

Я пытаюсь сохранить уникальный массив элементов String с помощью MongoDB, но по какой-то причине он позволяет сохранять дубликаты.Сохранение уникальных элементов массива MongoDB

Я использую мангуст. Мой код:

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

В основном речь идет, чтобы сохранить список адресов электронной почты, когда пользователь послал электронные письма и не позволяет пользователю спамить их. Но эта схема позволит мне нажимать любую строку на массив sharedTo и на .save() это независимо от того, существуют ли дубликаты. Как предотвратить это?

EDIT: Ответ Lahar помогает с моим вопросом, но не в полном объеме. Я хотел бы запретить пользователю добавлять электронные письма, если есть в наименее один дубликат. Таким образом, в основном $ addToSet поможет с уникальностью, но не с моим вопросом.

+0

Можете ли вы привести примеры вида повторяющихся записей, вы пытаетесь предотвратить, что она что позволяет? –

ответ

0

Похоже, я нашел решение самостоятельно, но благодаря ответу Лахар Шаха, указав мне в правильном направлении. Вместо того чтобы использовать

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

Вы можете использовать $ addToSet вместо $ нажмите, чтобы добавить электронную почту в массиве «sharedTo». Это не будет добавлять повторяющийся элемент (электронная почта в вашем случае).

Посредством предоставления уникального: true для целого массива поле не проверяет уникальность элемента массива.

Пожалуйста, проверьте документацию $addToSet.

+0

Это почти тот ответ, который мне нужен. Проблема в том, что я хочу выкинуть ошибку, если есть дубликат и вернуться к конфликту 409. Возможно ли это? – Rouz

+0

Итак, когда вы запустите это обновление, он возвращает объект writeResult со счетчиком nMatched, nUpserted, nModified. nModified сообщит вам, сколько документов было изменено. –

+0

Да, но он сохраняет объект в базе данных, поэтому технически мне придется откатываться к предыдущей версии, если измененный размер меньше длины ввода? Это звучит как грязное и неправильное решение, не так ли? – Rouz

 Смежные вопросы

  • Нет связанных вопросов^_^