Jeśli to możliwe, sugeruję ustawienie warunku podczas przechowywania danych, aby można było szybko sprawdzić prawdziwość (isInStudentsList
). Wykonanie tego typu zapytania byłoby bardzo szybkie.
W przeciwnym razie istnieje stosunkowo złożony sposób wykorzystania potoku struktury agregacji do wykonania tego, co chcesz w jednym zapytaniu:
db.students.aggregate(
{$project:
{studentId: 1, studentIdComp: "$students.id"}},
{$unwind: "$studentIdComp"},
{$project : { studentId : 1,
isStudentEqual: { $eq : [ "$studentId", "$studentIdComp" ] }}},
{$match: {isStudentEqual: true}})
Biorąc pod uwagę przykład wprowadzania danych, wynik będzie następujący:
{
"result" : [
{
"_id" : ObjectId("517b88decd483543a8bdd95b"),
"studentId" : 23,
"isStudentEqual" : true
}
],
"ok" : 1
}
Krótkie wyjaśnienie kroków:
- Zbuduj projekcję dokumentu za pomocą
studentId
i nowe pole z tablicą zawierającą tylkoid
(więc pierwszy dokument będzie zawierał[23, 55]
. - Korzystając z tej struktury, $unwind
. To tworzy nowy tymczasowy dokument dla każdego elementu tablicy w
studentIdComp
tablica. - Teraz weź te dokumenty i utwórz nową projekcję dokumentu, która nadal będzie miała
studentId
i dodaje nowe pole o nazwieisStudentEqual
który porównuje równość dwóch pól,studentId
istudentIdComp
. Pamiętaj, że w tym momencie istnieje jeden tymczasowy dokument, który zawiera te dwa pola. - Na koniec sprawdź, czy wartość porównania
isStudentEqual
jest prawdziwe i zwraca te dokumenty (które będą zawierać oryginalny dokument_id
istudentId
. - Jeśli uczeń był na liście wiele razy, może być konieczne pogrupowanie wyników według
studentId
lub_id
aby zapobiec duplikatom (ale nie wiem, czy tego potrzebujesz).