Het verschil in projectiegebruik is enigszins subtiel. In uw voorbeeldgebruik zouden dit equivalente zoekopdrachten moeten zijn (in termen van indexgebruik), maar de $elemMatch
voorbeeld herhaalt onnodig de zoekcriteria. De $
projectie zou voor dit voorbeeld een verstandiger keuze zijn.
Een essentieel verschil dat in de documentatie wordt opgemerkt, is de array veldbeperking
voor $
projecties:
Enkele verdere opmerkingen over de verschillen in de projectie-operators hieronder ...
De positionele ($
) projectie-operator
:
-
beperkt de inhoud van een matrixveld dat is opgenomen in de queryresultaten om het eerste element te bevatten dat overeenkomt met het querydocument.
-
vereist dat het overeenkomende matrixveld is opgenomen in de zoekcriteria
-
kan alleen worden gebruikt als een enkel matrixveld voorkomt in de zoekcriteria
-
kan maar één keer worden gebruikt in een projectie
De $elemMatch
projectie-operator
-
beperkt de inhoud van een arrayveld dat is opgenomen in de queryresultaten om alleen het eerste arrayelement dat overeenkomt met de $elemMatch-voorwaarde te bevatten .
-
vereist niet dat de overeenkomende array in de zoekcriteria staat
-
kan worden gebruikt om aan meerdere voorwaarden te voldoen voor array-elementen die ingesloten documenten zijn
De $elemMatch
query-operator
Merk op dat er ook een $elemMatch
. is query-operator die vergelijkbare overeenkomsten uitvoert, maar in de query in plaats van in de resultaatprojectie. Het is niet ongebruikelijk dat dit wordt gebruikt in combinatie met een $
projectie.
Een voorbeeld uit de documenten lenen waar je beide zou kunnen gebruiken:
db.students.find(
// use $elemMatch query operator to match multiple criteria in the grades array
{ grades: {
$elemMatch: {
mean: { $gt: 70 },
grade: { $gt: 90 }
}
}},
// use $ projection to get the first matching item in the "grades" array
{ "grades.$": 1 }
)