MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Ottieni valori distinti dall'array in base alle condizioni all'interno dell'array

Condizioni di query con .distinct() si applicano alla "selezione del documento" e non alle voci dell'array contenute "all'interno" del documento. Se è necessario "filtrare" il contenuto dell'array, applicare .aggregate() invece, oltre a una piccola post-elaborazione per ottenere solo i "valori" nella risposta dell'array.

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

Le parti principali sono $unwind fase della pipeline che si esegue principalmente perché si desidera che i valori all'interno dell'array vengano utilizzati in seguito come chiave per $group Su. Ciò produce essenzialmente un nuovo documento per ogni membro della matrice, ma ogni documento contiene solo quel membro della matrice. È "denormalizzante" per le strutture MongoDB che contengono array.

La prossima cosa è il seguente $match pipeline, che funziona come qualsiasi query e seleziona solo i documenti che soddisfano le condizioni. Poiché tutti i membri dell'array sono ora "documenti", le voci non corrispondenti (come documenti) vengono escluse. In alternativa puoi utilizzare $filter per estrarre mentre è ancora un array, ma poiché abbiamo bisogno di $unwind per la fase successiva potremmo anche semplicemente $match .

A questo punto rimangono solo le voci dell'array che soddisfano le condizioni. Il $group è ottenere valori "distinti", quindi in genere lo faresti su una selezione più ampia rispetto a un singolo documento o qualsiasi cosa in cui i valori qui non siano già distinti. Quindi questo è davvero solo mantenere lo stesso comportamento di .distinct() intatto.

Infine, dall'output di .aggregate() differisce dal design di .distinct() in quanto restituisce "documenti" nei risultati, utilizziamo semplicemente il .map() metodo per elaborare i risultati del cursore e restituire solo i "valori" dalla specifica proprietà del documento come "array".