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".