Условия на заявка с .distinct()
се прилага за „избор на документ“, а не за записите в масива, съдържащи се „в“ документа. Ако трябва да „филтрирате“ съдържанието на масива, тогава прилагате .aggregate()
вместо това, както и малка последваща обработка, за да получите само „стойностите“ в отговора на масива.
db.collection.aggregate([
{ "$match": { "_id": "TEST" } },
{ "$unwind": "$payload" },
{ "$match": { "payload.status": { "$in": ["TRUE","FALSE"] } } },
{ "$group": { "_id": "$payload._id" } },
]).map( d => d._id );
Основните части там са $unwind
етап на тръбопровод, който правите основно, защото искате стойностите от масива да се използват по-късно като ключ към $group
На. Това по същество създава нов документ за всеки член на масива, но всеки документ съдържа само този член на масива. Това е „денормализиращо“ за MongoDB структури, които съдържат масиви.
Следващото нещо е следното $match
pipeline, който работи като всяка заявка и избира само документи, които отговарят на условията. Тъй като всички членове на масива вече са "документи", тогава несъвпадащите записи (като документи) се изключват. Можете алтернативно да използвате $filter
за извличане, докато все още е масив, но тъй като имаме нужда от $unwind
за следващия етап можем просто да $match
.
В този момент ви остават само записите в масива, които отговарят на условията. $group
е да получите "различни" стойности, така че обикновено бихте направили това върху по-широка селекция от само един документ или нещо, където стойностите тук вече не са различни. Така че това наистина е просто запазване на едно и също поведение на .distinct()
непокътнати.
И накрая, тъй като резултатът от .aggregate()код>
се различава от дизайна на .distinct()код>
тъй като връща „документи“ в резултатите, ние просто използваме .map()
метод за обработка на резултатите от курсора и връщане само на „стойностите“ от конкретното свойство на документа като „масив“.