Mongoose valeurs uniques dans un tableau imbriqué d'objets

pour mon projet, je veux garder un document Mangoose pour les groupes d'organisations, comme ceci:

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

je veux éviter que le même utilisateur d'être dans le même groupe deux fois. Pour ce faire, je dois forcer les utilisateurs.uid être unique dans le tableau. J'ai essayé de dire "unique : true" pour uid, mais ça n'a pas marché. Y a-t-il un moyen de le faire avec mongoose ou mongoDB sans requêtes supplémentaires ou fractionnement du schéma?

Modifier: J'ai changé la valeur précédente de liquide à uid : { type : Schéma.Type.ObjectId, ref : 'Utilisateur', l'index: {unique: true, dropDups: vrai} } Mais cela ne semble pas fonctionner.

Edit: en supposant qu'il n'y a pas de moyen simple pour atteindre ceci, j'ai ajouté une requête supplémentaire vérifiant si l'utilisateur est déjà dans le groupe. Cela me semble la manière la plus simple.

19
demandé sur Guido Passage 2013-04-10 13:16:17

2 réponses

un index unique sur un champ de tableau impose que la même valeur ne puisse pas apparaître dans les tableaux de plus d'un document dans la collection, mais n'empêche pas la même valeur d'apparaître plus d'une fois dans un même document du tableau. Vous devez donc vous assurer de l'unicité lorsque vous ajoutez des éléments au tableau à la place.

$addToSet opérateur pour ajouter une valeur à un tableau uniquement si la valeur n'est pas déjà présent.

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

cependant, si le users le tableau contient des objets avec des propriétés multiples et vous voulez assurer l'unicité sur un seul d'entre eux (uid dans ce cas), alors vous devez prendre une autre approche:

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

ce que cela fait est de qualifier le $push mise à jour seulement se produire si user.uid n'existe pas déjà dans le uid champ de l'un quelconque des éléments de users. Donc, il imite $addToSet comportement, mais pour juste uid.

63
répondu JohnnyHK 2015-10-31 14:55:19
$addToSet opérateur.

l'opérateur $ addToSet ajoute une valeur à un tableau à moins que la valeur soit déjà présente, auquel cas $addToSet ne fait rien à ce tableau.

exemple:

MyModal.update(
   { _id: 1 },
   { $addToSet: {letters: [ "c", "d" ] } }
)
0
répondu Ankit Balyan 2018-09-20 20:12:57