2013-04-10 4 views
19

Для моего проекта, я хочу, чтобы сохранить мангуста документ для групп организаций, например:Mongoose Уникальные значения в гнездовой массив объектов

var groupSchema = Schema({ 
    name : { type : String }, 
    org : { type : Schema.Types.ObjectId, ref : 'Organization' }, 
    ... 
    users : [{ 
    uid : { type : Schema.Types.ObjectId, ref : 'User' }, 
    ... 
    }] 
}); 

Я хочу, чтобы предотвратить такую ​​же пользователю быть в одной и той же группе дважды. Для этого мне нужно заставить users.uid быть уникальным в массиве users. Я попытался указать «unique: true» для uid, но это не сработало. Есть ли способ сделать это с помощью mongoose или mongoDB без дополнительных запросов или разделения схемы?

Edit: Я изменил предыдущее значение UID для UID: {типа: Schema.Types.ObjectId, ссылка: 'User', индекс: {уникальный: true dropDups: истинный}} Но это еще Безразлично Кажется, он работает.

Редактировать: Предполагая, что для этого нет простого способа, я добавил дополнительный запрос, если пользователь уже находится в группе. Это кажется мне самым простым способом.

+0

проверить это будет [полезно] (http://stackoverflow.com/questions/12395118/mongodb-setting-unique-field) – karthick

+0

Благодарим вас за ссылку. Я пробовал следующее: uid: {type: Schema.Types.ObjectId, ref: 'User', index: {unique: true, dropDups: true}} вместо старого значения для uid. Это все еще не работает, я также попытался перезапустить mongoDB без успеха. –

ответ

61

Уникальный индекс в поле массива предусматривает, что одно и то же значение не может отображаться в массивах более одного документа в коллекции, но не препятствует тому, чтобы одно и то же значение появлялось более одного раза в массиве одного документа , Поэтому вам нужно обеспечить уникальность при добавлении элементов в массив.

Используйте оператор $addToSet, чтобы добавить значение к массиву, только если это значение еще не присутствует.

Group.update({name: 'admin'}, {$addToSet: {users: userOid}}, ... 

Однако, если users массив содержит объекты с несколькими свойствами, и вы хотите, чтобы обеспечить уникальность над только один из них (uid в данном случае), то вам необходимо принять другой подход:

var user = { uid: userOid, ... }; 
Group.update(
    {name: 'admin', 'users.uid': {$ne: user.uid}}, 
    {$push: {users: user}}, 
    function(err, numAffected) { ... }); 

То, что делает, относится к обновлению $push, только если user.uid еще не существует в поле uid любого из элементов users. Поэтому он имитирует поведение $addToSet, но всего лишь uid.

+0

Но как вы можете заставить только uid быть уникальным? В массиве users у меня больше атрибутов, которые могут быть разными при каждом добавлении одного и того же пользователя (например, даты). –

+0

Благодарим вас за ввод. Я читал о валидаторах, но я не вижу более простого способа, чем добавление дополнительной проверки запроса, если пользователь уже находится в группе. –

+0

@GuidoPassage Я добавил способ поддержать ваш конкретный вариант использования. – JohnnyHK

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