I have documents similar to the following:
db.etudiants.insert(
{
nom:'emile',
prenom:'zola',
cours_reussis:[
{
intitule: ['PAI'],
Periodes: NumberInt(60),
note: 60,
date_reussite: NumberInt(2014),
dispense: true,
nom_ecole:'EPFC'
},
{
intitule:'TGP',
Periodes: NumberInt(40),
note:75,
date_reussite: NumberInt(2013),
dispense: true,
nom_ecole: 'HEB'
},
{
intitule: 'SO2',
Periodes: NumberInt(60),
note: 70,
date_reussite: NumberInt(2015),
dispense: true,
nom_ecole: 'ISFCE'
},
{
intitule: 'IBD',
Periodes: NumberInt(60),
note: 80,
date_reussite: NumberInt(2015),
dispense:true,
nom_ecole:'ISFCE'
}
]
}
)
How can query matching documents and return nom_ecole: 'ISFCE'
and year (date_reussite
) from the cours_reussis
array?
2 Answers 2
If you want to return a subset of matching array elements in a MongoDB document, the best approach to do so is using the Aggregation Framework. The Aggregation Framework processes data similar to a Unix pipeline: the output of each aggregation stage is passed as input to the next:
db.etudiants.aggregate([
// Find relevant documents: this can take advantage of an index, if applicable
{ $match: {
'cours_reussis.nom_ecole': 'ISFCE',
}},
// Expand cours_reussis array into a stream of documents
{ $unwind: '$cours_reussis' },
// Filter based on matching array elements
{ $match: {
'cours_reussis.nom_ecole': 'ISFCE',
}},
// Project desired subset of fields
{ $project: {
'_id': "$_id",
'nom': '$nom',
'prenom': '$prenom',
'cours_reussis' : { 'nom_ecole': 1, date_reussite: 1 }
}},
// Regroup data as per the original document _id
{ $group: {
_id: "$_id",
nom: { $first: "$nom" },
prenom: { $first: "$prenom" },
cours_reussis: { $push: "$cours_reussis" }
}}
])
You can debug the aggregation pipeline by starting with a single stage and then adding on additional stages one at a time assuming you are seeing the expected output.
Sample output from MongoDB 3.2:
{
"_id": ObjectId("58462f40f8475aba9f391216"),
"nom": "emile",
"prenom": "zola",
"cours_reussis": [
{
"date_reussite": 2015,
"nom_ecole": "ISFCE"
},
{
"date_reussite": 2015,
"nom_ecole": "ISFCE"
}
]
}
You can use Aggregation Pipeline Stages Operators, In the db.collection.aggregate method, pipeline stages appear in an array. Documents pass through the stages in sequence.
Note :
For details on specific operator, including syntax and examples, click on the specific operator to go to its reference page.
For Syntax
db.collection.aggregate( [ { <stage> }, ... ] )
$match (aggregation)
Filters the documents to pass only the documents that match the specified condition(s) to the next pipeline stage.
The $match stage has the following prototype form:
{ $match: { <query> } }
As here mention below there is your documents details
After using the $match (aggregation) operator to filters the documents to pass only the documents that match the specified condition(s) to the next pipeline stage.
Behavior
Pipeline Optimization
Place the $match as early in the aggregation pipeline as possible. Because $match limits the total number of documents in the aggregation pipeline, earlier $match operations minimize the amount of processing down the pipe.
If you place a $match at the very beginning of a pipeline, the query can take advantage of indexes like any other db.collection.find() or db.collection.findOne().