Vérifier Si le champ existe dans un sous-document d'un Tableau
J'ai un schéma qui est semblable à cela.
{id: Number,
line_items: [{
id: String,
quantity: Number,
review_request_sent :Boolean
}],
total_price: String,
name: String,
order_number: Number
}
Ce que je veux savoir est que tous les éléments qui n'ont pas de définir le champ review_request_sent pour tous les éléments dans le tableau.
Exemple
{
id: 1,
line_items: [
{
id: 43,
review_request_sent: true
}
]
},
{
id: 2,
line_items: [
{
id: 1,
review_request_sent: false
},
{
id: 39
},
]
},
{
id: 3,
line_items: [
{
id: 23,
review_request_sent: true
},
{
id: 85,
review_request_sent: true
},
{
id: 12,
review_request_sent: false
}
]
}
Je voudrais de l'aide avec une requête/trouver qui sera de retour que le seccond document parce qu'il n'a pas le review_request_sent champ dans tous ses éléments dans son tableau.
OriginalL'auteur user841818 | 2015-09-02
Vous devez vous connecter pour publier un commentaire.
Fondamentalement, vous voulez
$elemMatch
et la$exists
de l'opérateur, ce qui permettra d'inspecter chaque élément pour voir si la condition "champ n'existe pas" est vrai pour n'importe quel élément:Qui renvoie le deuxième document que le champ n'est pas présent dans l'un de la matrice sous-documents:
Noter que cette "diffère" à partir de ce formulaire:
Où ce qui est demandé ne "toutes" les éléments du tableau contient pas de ce champ, qui n'est pas vrai lorsqu'un document a au moins un élément qui a le champ. Ainsi, le
$eleMatch
sorte que la condition testée par rapport à la "chaque" élément de tableau, et donc vous avez la réponse correcte.Si vous vouliez mettre à jour ces données, de sorte que tout élément de tableau trouvé qui ne contiennent pas de ce champ devait ensuite recevoir ce champ avec une valeur de
false
( sans doute ), vous pouvez même écrire une déclaration comme ceci:Où la
.aggregate()
non seulement le résultat correspond à l'documents, mais les filtres de contenu à partir du tableau où le champ n'était pas présent, afin que le juste retour de la "id" de la sous-document.Puis la boucle
.update()
états correspondent chacun a trouvé l'élément de tableau dans chaque document et ajoute le manque de champ avec une valeur à la position correspondante.De cette façon, vous aurez le champ présent dans tous les sous-documents de tous les documents où il manquait avant.
Si vous voulez faire une telle chose, alors il serait sage de changer votre schéma assurez-vous que le champ est toujours là:
Donc, la prochaine fois vous ajoutez de nouveaux éléments dans le tableau dans le code de l'élément existera toujours avec sa valeur par défaut si elle n'est pas définie de façon explicite. Et c'est probablement une goood idée de le faire, ainsi que la mise en
required
sur d'autres champs que vous voulez toujours, comme "id".$elemMatch ne retourne que le premier match. Si vous voulez de plus?
C'est ce qui a fonctionné pour moi
db.history.find({"treat":{ "$elemMatch": {"nameOfPerson":{"$exists": true}}}})
Réponse parfaite. Triés une "tirer les cheveux", le type de problème que j'ai eu. Merci
OriginalL'auteur Blakes Seven
Vous pouvez trouver cela d'une autre manière sans
$map
et$unwind
utilisé $rédiger comme ceci :Dans la requête ci-dessus d'abord
match
vérifier sireview_request_sent
est présente ou non dansredact
$ifNull utiliser pour vérifier sireview_request_sent
présente ou non si non, alors il est remplacé à"null"
et$eq
pour vérifier"null"
ce sera le retour des documents, comme deset après le dernier match de vérifier que les documents dont
line_items
tableau contient la valeur que je.e $taille à 1OriginalL'auteur Yogesh
Si vous voulez juste pour obtenir le document en entier puis, comme mentionné par @Blakes Sept. Vous pouvez interroger l'aide de $elemMatch.
Mais si vous voulez filtrer l'élément de tableau et d'obtenir uniquement les éléments du tableau qui n'ont pas un certain domaine, alors vous pouvez utiliser filtre $ avec $type dans l'agrégation de pipeline.
Remarque: $type renvoie "manquant" lorsqu'il est utilisé avec undefined champs.
OriginalL'auteur Abhinandan Kothari