Un tableau dans un document
Un champ peut contenir une liste de valeurs simples, ou une liste de sous-documents. Exemple avec une campagne et ses commandes embarquées :
{
"zone": "Ladignac-le-Long",
"commandes": [
{ "litres": 1500, "commune": "Ladignac" },
{ "litres": 800, "commune": "Nexon" }
]
}
$all et $size
$all exige que le tableau contienne toutes les valeurs listées ; $size filtre sur le nombre d'éléments.
// documents dont le tableau tags contient à la fois "urgent" et "hiver" db.campagnes.find({ tags: { $all: ["urgent", "hiver"] } }) // campagnes ayant exactement 2 commandes db.campagnes.find({ commandes: { $size: 2 } })
{ tags: "hiver" }) teste la présence d'une valeur ; $all teste la présence de plusieurs valeurs à la fois.$elemMatch — une condition sur un élément
Pour un tableau de sous-documents, $elemMatch exige qu'un même élément satisfasse plusieurs conditions à la fois.
// campagnes ayant AU MOINS une commande de + de 1000 L à Ladignac db.campagnes.find({ commandes: { $elemMatch: { litres: { $gt: 1000 }, commune: "Ladignac" }} })
$elemMatch, écrire les deux conditions séparément accepterait un document où un élément a > 1000 L et un autre est à Ladignac. $elemMatch force le même élément à remplir les deux.Ajouter / retirer : $push et $pull
$push ajoute un élément à un tableau ; $pull retire les éléments qui correspondent à une condition. On les utilise dans un updateOne/updateMany.
// ajouter une commande à une campagne db.campagnes.updateOne( { zone: "Ladignac-le-Long" }, { $push: { commandes: { litres: 1200, commune: "Saint-Yrieix" } } } ) // retirer les commandes de Nexon db.campagnes.updateOne( { zone: "Ladignac-le-Long" }, { $pull: { commandes: { commune: "Nexon" } } } )
$addToSet et $pop
$addToSet ajoute une valeur seulement si elle n'y est pas déjà (évite les doublons) ; $pop retire le premier (-1) ou le dernier (1) élément.
db.campagnes.updateOne({ zone: "Ladignac-le-Long" },
{ $addToSet: { tags: "prioritaire" } }) // pas de doublon
db.campagnes.updateOne({ zone: "Ladignac-le-Long" },
{ $pop: { commandes: 1 } }) // retire la dernière
L'opérateur positionnel $
Comment modifier un élément précis d'un tableau ? L'opérateur positionnel $ désigne l'élément qui a correspondu au filtre.
// passer la commande de Ladignac à 1600 L db.campagnes.updateOne( { zone: "Ladignac-le-Long", "commandes.commune": "Ladignac" }, { $set: { "commandes.$.litres": 1600 } } )
$ reprend la position de l'élément trouvé par le filtre. Pour modifier tous les éléments correspondants, il existe l'opérateur $[] et les filtres arrayFilters.C'est le chapitre clé pour le fil rouge ! « Rejoindre une campagne » = un $push dans commandes. « Se désinscrire » = un $pull. « Corriger sa quantité » = l'opérateur positionnel $. Écris ces trois opérations : elles deviendront l'endpoint POST /campagnes/{id}/commandes et ses variantes dans l'API Spring.
- Chercher :
$all,$size,$elemMatch(même élément). - Ajouter/retirer :
$push,$pull,$addToSet,$pop. - Modifier un élément ciblé : l'opérateur positionnel
$.