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 })
Related
I'm practicing with mongo using the sample db restaurants.
The db has the following structure:
{
"_id" : ObjectId("6035397d0076410d79b29bde"),
"address" : {
"building" : "522",
"coord" : [
-73.95171,
40.767461
],
"street" : "East 74 Street",
"zipcode" : "10021"
},
"borough" : "Manhattan",
"cuisine" : "American ",
"grades" : [
{
"date" : ISODate("2014-09-02T00:00:00Z"),
"grade" : "A",
"score" : 12
},
{
"date" : ISODate("2013-12-19T00:00:00Z"),
"grade" : "B",
"score" : 16
},
{
"date" : ISODate("2013-05-28T00:00:00Z"),
"grade" : "A",
"score" : 9
},
{
"date" : ISODate("2012-12-07T00:00:00Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2012-03-29T00:00:00Z"),
"grade" : "A",
"score" : 11
}
],
"name" : "Glorious Food",
"restaurant_id" : "40361521"
}
{
"_id" : ObjectId("6035397d0076410d79b29bdf"),
"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"
}
What I'm trying to do is to get the total of cuisines per borought. So, if a borought has 5 resturants, but in this restaurants, 2 serve the same kind of food, my total should be 4.
I'm suposed to use map/reduce/finalize functions, but I can't figure out how.
All exemples I saw, in the map you have just one attribute to filter de data, but I need to group the restaurants of the same borough and then group e count by cuisine.
Can anyone help me? I've been tryng for a long time, didn't get enyware. The best I manage was to count the total of restaurants per borough.
Thank you.
Try this:
db.restaurants.aggregate([
// First group by "borough" and "cousine".
{
$group: {
_id: {
"borough": "$borough",
"cuisine": "$cuisine"
},
count: { $first: 1 }
}
},
// Second group by only "borough".
{
$group: {
_id: "$_id.borough",
count: { $sum: "$count" }
}
}
]);
Output:
/* 1 */
{
"_id" : "Brooklyn",
"count" : 1
},
/* 2 */
{
"_id" : "Manhattan",
"count" : 2
}
My test data:
/* 1 createdAt:2/24/2021, 11:35:10 PM*/
{
"_id" : ObjectId("6036955624f3423874ac9540"),
"borough" : "Manhattan",
"cuisine" : "Indian",
"restaurant_id" : "40361605"
},
/* 2 createdAt:2/24/2021, 11:35:10 PM*/
{
"_id" : ObjectId("6036955624f3423874ac953f"),
"borough" : "Brooklyn",
"cuisine" : "American",
"restaurant_id" : "40361606"
},
/* 3 createdAt:2/24/2021, 11:35:10 PM*/
{
"_id" : ObjectId("6036955624f3423874ac953e"),
"borough" : "Manhattan",
"cuisine" : "American",
"restaurant_id" : "40361522"
},
/* 4 createdAt:2/24/2021, 11:35:10 PM*/
{
"_id" : ObjectId("6036955624f3423874ac953d"),
"borough" : "Manhattan",
"cuisine" : "American",
"restaurant_id" : "40361521"
}
i'm working with the restaurants db in mongo
{
"_id" : ObjectId("5c66fcf59e184ea712adfba6"),
"address" : {
"building" : "97-22",
"coord" : [
-73.8601152,
40.7311739
],
"street" : "63 Road",
"zipcode" : "11374"
},
"borough" : "Queens",
"cuisine" : "Jewish/Kosher",
"grades" : [
{
"date" : ISODate("2014-11-24T00:00:00.000Z"),
"grade" : "Z",
"score" : 20
},
{
"date" : ISODate("2013-01-17T00:00:00.000Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2012-08-02T00:00:00.000Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2011-12-15T00:00:00.000Z"),
"grade" : "B",
"score" : 25
}
],
"name" : "Tov Kosher Kitchen",
"restaurant_id" : "40356068"
}
I'm tryng to filter with match in aggregate. I want to check if any score in grades is greater than 5
db.runCommand({
aggregate: "restaurants",
pipeline : [
{$match: {"grades": {$anyElementTrue: {"score": {$gt:5}}}}}
but i'm getting this error:
"errmsg" : "unknown operator: $anyElementTrue",
thanks
Try with $eleMatch
db.restaurants.aggregate([{$match: {"grades": {$elemMatch: {"score": {$gt:5}}}}}])
I have a mongodb db with 18625 collections. It has following keys:
"_id" : ObjectId("5aab14d2fc08b46adb79d99c"),
"game_id" : NumberInt(4),
"score_phrase" : "Great",
"title" : "NHL 13",
"url" : "/games/nhl-13/ps3-128181",
"platform" : "PlayStation 3",
"score" : 8.5,
"genre" : "Sports",
"editors_choice" : "N",
"release_year" : NumberInt(2012),
"release_month" : NumberInt(9),
"release_day" : NumberInt(11)
Now, i wish to create another dimension/ collection with only genres.
If i use the following query :
db.ign.aggregate([ {$project: {"genre":1}}, { $out: "dimen_genre" } ]);
It generates 18625 collections, even though there are only 113 distinct
genres.
How to apply distinct here and get the collection for genres with only the distinct 113 values.
I googled, bt it showed that aggregate and distinct don't work together in mongo.
I also tried : db.dimen_genre.distinct('genre').length
this showed that in dimension_genre, there are 113 distinct genres.
Precisely,
how to make a collection from existing one with only distinct values.
I am really new to NoSQLs.
You can use $addToSet to group unique values in one document and then $unwind to get back multiple docs:
db.ign.aggregate([
{
$group: {
_id: null,
genre: { $addToSet: "$genre" }
}
},
{
$unwind: "$genre"
},
{
$project: {
_id: 0
}
},
{ $out: "dimen_genre" }
]);
You can try
db.names.aggregate(
[
{ $group : { _id : "$genre", books: { $push: "$$ROOT" } } }
]
)
I have tried with Test and Sports as genre
It gives you output something like this
{
"_id" : "Test",
"books" : [
{
"_id" : ObjectId("5aaea6150cc1403ee9a02e0c"),
"game_id" : 4,
"score_phrase" : "Great",
"title" : "NHL 13",
"url" : "/games/nhl-13/ps3-128181",
"platform" : "PlayStation 3",
"score" : 8.5,
"genre" : "Test",
"editors_choice" : "N",
"release_year" : 2012,
"release_month" : 9,
"release_day" : 11
}
]
}
/* 2 */
{
"_id" : "Sports",
"books" : [
{
"_id" : ObjectId("5aaea3be0cc1403ee9a02d97"),
"game_id" : 4,
"score_phrase" : "Great",
"title" : "NHL 13",
"url" : "/games/nhl-13/ps3-128181",
"platform" : "PlayStation 3",
"score" : 8.5,
"genre" : "Sports",
"editors_choice" : "N",
"release_year" : 2012,
"release_month" : 9,
"release_day" : 11
},
{
"_id" : ObjectId("5aaea3c80cc1403ee9a02d9b"),
"game_id" : 4,
"score_phrase" : "Great",
"title" : "NHL 13",
"url" : "/games/nhl-13/ps3-128181",
"platform" : "PlayStation 3",
"score" : 8.5,
"genre" : "Sports",
"editors_choice" : "N",
"release_year" : 2012,
"release_month" : 9,
"release_day" : 11
},
{
"_id" : ObjectId("5aaea3cf0cc1403ee9a02d9f"),
"game_id" : 4,
"score_phrase" : "Great",
"title" : "NHL 13",
"url" : "/games/nhl-13/ps3-128181",
"platform" : "PlayStation 3",
"score" : 8.5,
"genre" : "Sports",
"editors_choice" : "N",
"release_year" : 2012,
"release_month" : 9,
"release_day" : 11
}
]
}
I'm just starting out with Mongo, and following the documentation here, I can't seem to update a value in a nested array when I apply the same technique.
This is my document:
{
"_id" : ObjectId("56d2cf8ee2b075667d4f0545"),
"address" : {
"building" : "522",
"coord" : [
-73.95171,
40.767461
],
"street" : "East 74 Street",
"zipcode" : "10021"
},
"borough" : "Manhattan",
"cuisine" : "American ",
"grades" : [
{
"date" : ISODate("2014-09-02T00:00:00Z"),
"grade" : "A",
"score" : 12
},
{
"grade" : "B",
"score" : 16,
"date" : ISODate("2013-12-19T00:00:00Z")
},
{
"date" : ISODate("2013-05-28T00:00:00Z"),
"grade" : "A",
"score" : 9
},
{
"date" : ISODate("2012-12-07T00:00:00Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2012-03-29T00:00:00Z"),
"grade" : "A",
"score" : 11
}
],
"name" : "Glorious Food",
"restaurant_id" : "40361521"
}
and this is my query:
db.restaurants.update(
{
_id: 'ObjectId("56d2cf8ee2b075667d4f0545")',
'grades.date': 'ISODate("2014-09-02T00:00:00Z")'
},
{
$set: { 'grades.$.score': 1 }
}
)
I'm sure I must have missed something obvious.
remove quotes from objectId and date field - please see below:
db.restaurants.update(
{
_id: ObjectId("56d2cf8ee2b075667d4f0545"),
"grades.date": ISODate("2014-09-02T00:00:00Z")
},
{
$set: { 'grades.$.score': 1 }
}
)
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 } )