How to query element in array of arrays in MongoDB? - mongodb

I'm learning MongoDB on my own. I have a collection with entries that look like this:
{
"_id" : ObjectId("5d0c13fbfdca455311248d6f"),
"borough" : "Brooklyn",
"grades" :
[
{ "date" : ISODate("2014-04-16T00:00:00Z"), "grade" : "A", "score" : 5 },
{ "date" : ISODate("2013-04-23T00:00:00Z"), "grade" : "B", "score" : 2 },
{ "date" : ISODate("2012-04-24T00:00:00Z"), "grade" : "A", "score" : 5 }
],
"name" : "C & C Catering Service",
"restaurant_id" : "40357437"
}
And I want to find all restaurants in Brooklyn with at least one grades.grade of A.
I've figured out the first half of the puzzle:
db.restaurants.find({borough:{$eq:"Brooklyn"}})
But how do I query in the "grades" array for grade A?

Use dot (.) to access and query nested objects:
db.restaurants.find({'borough':{$eq:"Brooklyn"}, 'grades.grade': 'A'})

db.restaurants.find({"borough" : "Brooklyn","grades.grade":"A"})

Related

MongoDB addToSet in nested array

I'm struggling to insert data inside a nested array in MongoDB.
My schema looks like this:
{
"_id" : ObjectId("5c0c55642440311ff0353846"),
"name" : "Test",
"email" : "test#gmail.com",
"username" : "test",
"password" : "$2a$10$RftzGtgM.DqIiaSvH4LqOO6RnLgQfLY3nk7UIAH4OAvvxo0ZMSaHu",
"created" : ISODate("2018-12-08T23:36:04.464Z"),
"classes" : [
{
"_id" : ObjectId("5c0c556e2440311ff0353847"),
"cName" : "1A",
"student" : [
{
"grades" : [ ],
"_id" : ObjectId("5c0c55812440311ff0353848"),
"name" : "StudentName",
"lname" : "StudenteLastName",
"gender" : "M"
}
insert }
],
"__v" : 0
}.
What I want to do is inserting a grade for the student inside "grades" array.
Expected result is:
{
"_id" : ObjectId("5c0c55642440311ff0353846"),
"name" : "Test",
"email" : "test#gmail.com",
"username" : "test",
"password" : "$2a$10$RftzGtgM.DqIiaSvH4LqOO6RnLgQfLY3nk7UIAH4OAvvxo0ZMSaHu",
"created" : ISODate("2018-12-08T23:36:04.464Z"),
"classes" : [
{
"_id" : ObjectId("5c0c556e2440311ff0353847"),
"cName" : "1A",
"student" : [
{
"grades" : [6],
"_id" : ObjectId("5c0c55812440311ff0353848"),
"name" : "StudentName",
"lname" : "StudenteLastName",
"gender" : "M"
}
]
}
],
"__v" : 0
}.
I tried some queries but none of them helped me, even searching a lot.
db.teachers.update({"_id": ObjectId("5c0c55642440311ff0353846"), "classes._id": ObjectId("5c0c556e2440311ff0353847"), "classes.student._id": ObjectId("5c0c55812440311ff0353848")},{$addToSet: {"classes.$.student.grades":6}})
Basically, I searched for the student with the first curly bracket (if I do "db.teachers.find(the three conditions) the result is correct) and then add to the grades array (of Integer) the value 6. But at this point I get errors, I think I'm making a mistake on the "adding" part.
I need also to do the same thing in Mongoose.
Any help is appreciated, thanks in advance!
Edit: I solved. I post my solution hoping it'll be useful to other:
For pushing inside a triple nested array do:
db.teachers.update({"_id":ObjectId("5c0c59985ae5981c58937e12"),"classes":{ $elemMatch : { _id : ObjectId("5c0c59a35ae5981c58937e13") }},"classes.student": { $elemMatch : { _id : ObjectId("5c0c59aa5ae5981c58937e14")} }},{$addToSet:{"classes.$.student.0.grades":3}})
https://docs.mongodb.com/manual/tutorial/query-array-of-documents/
Try using $elemMatch
"classes":{ $elemMatch : { _id : ObjectId("5c0c556e2440311ff0353847") }},
"classes.student": { $elemMatch : { _id : ObjectId("5c0c55812440311ff0353848")} }

MongoDB : Push data to a map

I have employee json as below in db, I want to create a map of "addressId"(key) and "city"(value) and return the result.
{
"_id" :1,
"_class" : "com.entity.Employee",
"clientId" : 1,
"addresses" : [
{
"addressId" : 1,
"street" : "ghi",
"city" : "Hyderabad"
},
{
"addressId" : 2,
"street" : "abc",
"city" : "Bangalore"
},
{
"addressId" : 3,
"street" : "def",
"city" : "Chennai"
}
]
}
Please suggest me which operator can I use and whether this can be achieved using $project.
Yes you have to use projection with unwind and forEach to make key value pair
try below mongo query
db.collection_name.aggregate([{"$unwind":"$addresses"},{"$project": {"addressId": "$addresses.addressId", "city":"$addresses.city", "_class":"$_class","clientId":"$clientId"} }]).forEach(function(ojb){ojb[ojb.addressId]=ojb.city; printjson(ojb);});

How to query mongodb with embedded document

Hi i'm practicing mongodb and I'm stuck with a problem. I'av the following set of documents.
{
"_id" : ObjectId("57cf9a134607674792dbad9e"),
"address" : {
"building" : "351",
"coord" : [
-73.9851356,
40.7676919
],
"street" : "West 57 Street",
"zipcode" : "10019"
},
"borough" : "Manhattan",
"cuisine" : "Irish",
"grades" : [
{
"date" : ISODate("2014-09-06T00:00:00.000Z"),
"grade" : "A",
"score" : 2
},
{
"date" : ISODate("2013-07-22T00:00:00.000Z"),
"grade" : "A",
"score" : 11
},
{
"date" : ISODate("2012-07-31T00:00:00.000Z"),
"grade" : "A",
"score" : 12
},
{
"date" : ISODate("2011-12-29T00:00:00.000Z"),
"grade" : "A",
"score" : 12
}
],
"name" : "Dj Reynolds Pub And Restaurant",
"restaurant_id" : "30191841"
}
I want to fetch list of all documents where zipcode is 10019
I'm following mongodb db tutorials and i've tried the following queries but nothing seems to work and i'm getting zero errors.
db.restaurants.find({address:{zipcode:10019}});
db.restaurants.find({"address.zipcode":10019})
zipcode is a string so your query should be
db.restaurants.find({ "address.zipcode": "10019" })
instead of
db.restaurants.find({ "address.zipcode": 10019 })

MongoDB and aggragate the embeded document

I am new to mongoDB and I came across a problem. The data was imported according to official doc.
As you can see, each of restaurant has a grades array and the nested document contains a score field. What I want to do is according to the average score of each restaurant's grades and retrive the restaurant that has the top average score. This may need to use mongoDB's aggregate method but the document doesn't cover the nested document situation and I googled but without a result. There's a similar question on this site but it's not so clear.
[
{ "_id" : ObjectId("56a9f39cae1902590811dffc"),
"address" : { "building" : "284",
"coord" : [ -73.9829239, 40.6580753 ],
"street" : "Prospect Park West",
"zipcode" : "11215" },
"borough" : "Brooklyn",
"cuisine" : "American ",
"grades" : [ { "date" : ISODate("2014-11-19T00:00:00Z"), "grade" : "A", "score" : 11 },
{ "date" : ISODate("2013-11-14T00:00:00Z"), "grade" : "A", "score" : 2 },
{ "date" : ISODate("2012-12-05T00:00:00Z"), "grade" : "A", "score" : 13 },
{ "date" : ISODate("2012-05-17T00:00:00Z"), "grade" : "A", "score" : 11 } ],
"name" : "The Movable Feast",
"restaurant_id" : "40361606" },
...
]
Using the mongo shell, try the below , change "collecttionname" to the name of your your restaurant collections
db.collectionname.aggregate( { '$unwind' : '$grades' } , { '$group' : { '_id' : '$_id' , 'average' : { $avg : '$grades.score' } } } , { '$sort' : { 'average' : -1 } } , { '$limit' : 1 } )

How to count all occurrences of an element in MongoDB?

Let's say I have the following entries in my MongoDB.
{ "_id" : ObjectId("5474af69d4b28042fb63b81b"), "name" : "a", "time" : NumberLong("1412774562000"), "location" : "DE" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81c"), "name" : "b", "time" : NumberLong("1412774562020"), "location" : "DE" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81d"), "name" : "c", "time" : NumberLong("1412774562040"), "location" : "US" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81e"), "name" : "d", "time" : NumberLong("1412774562060"), "location" : "AU" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81f"), "name" : "e", "time" : NumberLong("1412774562080"), "location" : "CN" }
As a result, I need to know how often each specific "location" can be found in the database e.g.
{"DE": "2",
"US": "1",
"AU": "1",
"CN": "1"}
I have no information about all the different locations in the database so querying after a known location for example
db.c.find({"location": "DE"})
would not solve my problem.
You need to make use of the aggregation pipeline with a group and project stage operators.
db.c.aggregate([
{$group:{"_id":"$location","count":{$sum:1}}},
{$project:{"location":"$_id","occurance":"$count"}}
])