From docs :
Use the $ in the projection document of the find () method or the findOne () method when you need only one specific array element in the selected documents.
The positional operator $
cannot be used at the design stage of the aggregation pipeline. There it is not recognized.
This makes sense because when you perform a projection along with a search, entering the projection part of the query is a single document that matches the query. The matching context is known even during projection. Thus, for each document that matches the query, a design operator is applied, and then before the next match is found.
db.class.find({"students.name":"An"}, {"students.$":true})
When:
db.class.aggregate([ {$match:{"students.name":'An'}}, {$project:{"students.$":true}} ])
An aggregation pipeline is a set of steps. Each stage is completely unaware and independent of its previous or next stages. The set of documents goes through the stage completely before moving on to the next stage in the pipeline. The first step in this case is the $match
step, all documents are filtered based on the matching condition. Entering the design phase has now installed documents that have been filtered out as part of the matching phase.
Thus, the positional operator at the design stage does not make sense, because at the current stage it does not know on what basis the fields were filtered. Therefore, $
operators are not allowed as part of field paths.
Why does it work below?
db.class.aggregate([ { $match: { "students.name": "An" }, { $unwind: "$students" }, { $project: { "students": 1 } } ])
As you can see, the design phase receives a set of documents as input and designs the required fields. It does not depend on its previous and next stages.
source share