MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Obtenir des valeurs distinctes du tableau en fonction des conditions au sein du tableau

Conditions de requête avec .distinct() s'applique à la "sélection de document" et non aux entrées de tableau contenues "dans" le document. Si vous avez besoin de "filtrer" le contenu du tableau, vous appliquez .aggregate() à la place, ainsi qu'un peu de post-traitement pour obtenir uniquement les "valeurs" dans la réponse du tableau.

db.collection.aggregate([
  { "$match": { "_id": "TEST" } },
  { "$unwind": "$payload" },
  { "$match": { "payload.status": { "$in": ["TRUE","FALSE"] } } },
  { "$group": { "_id": "$payload._id" } },
]).map( d => d._id );

Les parties principales sont le $unwind étape de pipeline que vous effectuez principalement parce que vous souhaitez que les valeurs du tableau soient utilisées ultérieurement comme clé pour $group sur. Cela produit essentiellement un nouveau document pour chaque membre du tableau, mais chaque document ne contient que ce membre du tableau. C'est "dénormalisant" pour les structures MongoDB qui contiennent des tableaux.

La prochaine chose est la suivante $match pipeline, qui fonctionne comme n'importe quelle requête et ne sélectionne que les documents qui correspondent aux conditions. Étant donné que tous les membres du tableau sont désormais des "documents", les entrées non correspondantes (comme documents) sont exclues. Vous pouvez également utiliser $filter pour extraire tout en restant un tableau, mais puisque nous avons besoin de $unwind pour la prochaine étape, nous pouvons tout aussi bien simplement $match .

À ce stade, il ne vous reste que les entrées du tableau qui correspondent aux conditions. Le $group est d'obtenir des valeurs "distinctes", donc généralement vous feriez cela sur une sélection plus large qu'un seul document ou quoi que ce soit où les valeurs ici ne sont pas déjà distinctes. Donc, cela ne fait que conserver le même comportement de .distinct() intacte.

Enfin, depuis la sortie de .aggregate() diffère de la conception de .distinct() en ce qu'il renvoie des "documents" dans les résultats, nous utilisons simplement le .map() pour traiter les résultats du curseur et renvoyer uniquement les "valeurs" de la propriété de document spécifique sous forme de "tableau".