MongoDB: $addToSet/$pousser document uniquement si elle n'existe pas déjà
J'ai un lists
collection où chaque document dispose d'un tableau de members
. Chaque élément de la members
tableau est un document avec un email
la propriété, la création date
de la propriété, et quelques autres méta. J'ai un index unique sur members.email
pour éviter le même e-mail étant entré dans la même liste à deux reprises, mais je tiens à conserver l'original date
valeur. Malheureusement, ni $addToSet
ni $push
semblent le faire.
Exemple à l'aide de $push:
$lists->update(array('_id' => $list['_id'], 'members.email' => array('$ne' => $email)), array('$push' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
//etc.
))));
Et avec $addToSet:
$lists->update(array('_id' => $list['_id']), array('$addToSet' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
//etc.
))));
Les deux exemples, remplacer l'ensemble du document incorporé par le nouveau en raison (je suppose) l'unique date
valeur. Est-il possible de ne $push
le "membre" d'un document si members.email
n'existe pas déjà ou ai-je besoin pour ce faire de deux commandes?
Sinon, serait-il une meilleure évolutivité-sage de mettre le members
dans leur propre collection avec un parent_list
-comme la propriété?
OriginalL'auteur Kevin | 2010-12-05
Vous devez vous connecter pour publier un commentaire.
Dans mon expérience, la raison que vous ne pouvez pas "$" push " ou "$addToSet" c'est parce que votre cible "membres" est probablement un objet incorporé (ou converti en un après sa création). Vous ne pouvez utiliser que $pousser, $pushAll, $addToSet sur les tableaux...
Malheureusement pour nous, les développeurs php d'un curseur requête retourne toujours les données sous forme de tableaux, la meilleure façon de vérifier pour voir si quelque chose comme "membres" est un tableau ou un objet, est d'exécuter un find() dans le shell mongo et de regarder pour l'bouclés/crochets ( "{}" ou "[]" ) dans le résultat.
Espère que cette aide.
OriginalL'auteur bm_i
Pourquoi ne pas avoir une collection où vous stockez list_id, e-mail, added_date
Vous pouvez alors créer un index unique sur 2 touches list_id et e-mail. Qui l'empêcherait d'insertion
d'un enregistrement avec le même list_id et e-mail
Il n'y aura pas les documents incorporés. Vous pouvez toujours utiliser find() par list_id
OriginalL'auteur Dmitri
utilisation
$ne
dans la requête condiction pour filtrer les documents avec les membres de la même e-mail:OriginalL'auteur kelvinhust
Oui c'est possible. Découvrez l' $existe opérateur dans la mongoDB requêtes avancées section. Code $existe en une où la déclaration pour mettre à jour uniquement lorsque les membres de l'e-mail n'existe pas.
OriginalL'auteur Anthony Jack
IIUC, essayez d'utiliser Upsert une mise à jour de l'embedded doc (si celui-là) ou d'insérer (si aucun). Voir cette trop.
Quant à la deuxième question concernant l'évolutivité, c'est vraiment dépend de la... l'intégration de la doc dans le parent nécessitent des mises à jour plus difficile et plus grand extraction de données, mais de réduire l'extraction de requêtes comte.
OriginalL'auteur Hertzel Guinness