MongoDB Basic Shell Commands (part-5)
Array Operators
$elemMatch
$elemMatch
allows us to have access to the sub-document of an array field.
We have a database sample_training
, where one of the documents of the grades
collection looks like this:
{
"_id" : ObjectId("56d5f7eb604eb380b0d8d8d0"),
"student_id" : 0,
"scores" : [
{
"type" : "exam",
"score" : 84.72636832669608
},
{
"type" : "quiz",
"score" : 7.8865616909793435
},
{
"type" : "homework",
"score" : 22.860114572528147
},
{
"type" : "homework",
"score" : 80.85669686147487
}
],
"class_id" : 149
}
Now let us find all documents where the student in class 431 received a grade higher than 85 for any type of assignment:
db.grades.find({ "class_id": 431 },
{ "scores": { "$elemMatch": { "score": { "$gt": 85 } } }
}).pretty()
Or, find all documents where the student had an extra credit score:
db.grades.find({ "scores": { "$elemMatch": { "type": "extra credit" } }
}).pretty()
In a nutshell:
Array Operators and Sub-Documents
dot(.)
Notation
Let us look at the document structure of the trips
collection:
{
"_id" : ObjectId("572bb8222b288919b68abf5b"),
"tripduration" : 889,
"start station id" : 268,
"start station name" : "Howard St & Centre St",
"end station id" : 3002,
"end station name" : "South End Ave & Liberty St",
"bikeid" : 22794,
"usertype" : "Subscriber",
"birth year" : 1961,
"gender" : 2,
"start station location" : {
"type" : "Point",
"coordinates" : [
-73.99973337,
40.71910537
]
},
"end station location" : {
"type" : "Point",
"coordinates" : [
-74.015756,
40.711512
]
},
"start time" : ISODate("2016-01-01T00:01:06Z"),
"stop time" : ISODate("2016-01-01T00:15:56Z")
}
We can use dot
notation to access the field of subdocuments and we can go as deep as we want to access the field of a nested document just like a javascript object and array. Now look at the following query:
db.trips.findOne({ "start station location.type": "Point" })
Top-level subdocument field name is bold in the following picture:
This subdocument has two fields:
We can access those fields like this:
So the general rule is :
Look at the following query:
db.companies.find({ "relationships.0.person.last_name": "Zuckerberg" },
{ "name": 1 }).pretty()
Part-7 has an interesting discussion about aggregation pipeline. Have a look at it.
Thanks for reading, any correction or recommendation is welcome.