This question already has answers here:
Mongo average aggregation query with no group
(3 answers)
Closed 7 years ago.
Suppose that I have a collection like this:
{
_id: 1,
city: "New York",
state: "NY",
murders: 328
}
{
_id: 2,
city: "Los Angeles",
state: "CA",
murders: 328
}
...
The collection shows us the number of murders in all cities of USA. I'd like to calculate the average of murders in all the country. I tried to use
$group:
db.murders.aggregate([{$group: {_id:"$state", pop: {$avg:"$murders"} } }])
But I get as result the murders by state:
{ "_id" : "NY", "murders" : 200 }
{ "_id" : "NJ", "murders" : 150 }
{ "_id" : "CA", "murders" : 230 }
{ "_id" : "CT", "murders" : 120 }
My question is, how can I group this result to calculate an unique average? Something like this:
{ "_id" : "USA", "murders" : 175 }
Try grouping by null.
db.murders.aggregate([{$group: {_id:null, pop: {$avg:"$murders"} } }])
More-Info: mongo-average-aggregation-query-with-no-group
Related
I'm new to MongoDB and was looking through the docs a few nights ago and saw something that I haven't been able to locate since...
There was an option, I believe it was related to $text search, to treat an array of strings as if they were the same word. The syntax looked something like this:
["cheez", "cheese"],
["donut", "doughnut"],
["chips", "fries", "crisps"],
So a search for "chips" would return all documents indexed with "fries" or "crisps" even if they did not also have "chips".
Please tell me I wasn't dreaming!
YOU ARE NOT DREAMING
mongodb fuzzy text search
The following query searches the title field for the phrase naw yark. It uses the fuzzy default options where:
maxEdits allows up to two character variation of each term in the
given phrase to match the query to a document.
maxExpansions considers up to fifty similar terms for each term in
naw yark to find matches.
prefixLength is disabled.
The query also includes a $limit stage to limit the output to 10 results and a $project stage to:
Exclude all fields except title
Add a field named score
db.movies.aggregate([
{
$search: {
"text": {
"path": "title",
"query": "naw yark",
"fuzzy": {}
}
}
},
{
$limit: 10
},
{
$project: {
"_id": 0,
"title": 1,
score: { $meta: "searchScore" }
}
}
])
The above query returns the following results:
{ "title" : "New York, New York", "score" : 4.392756462097168 }
{ "title" : "New York", "score" : 4.050914287567139 }
{ "title" : "New York Stories", "score" : 3.4838104248046875 }
{ "title" : "New York Minute", "score" : 3.4838104248046875 }
{ "title" : "Synecdoche, New York", "score" : 3.4838104248046875 }
{ "title" : "New York Doll", "score" : 3.4838104248046875 }
{ "title" : "Little New York", "score" : 3.4838104248046875 }
{ "title" : "Escape from New York", "score" : 3.0559897422790527 }
{ "title" : "King of New York", "score" : 3.0559897422790527 }
{ "title" : "Naked in New York", "score" : 3.0559897422790527 }
also synonyms:
mongodb synonyms text search
Unlike the other question someone asked where they wanted only one item returned. I HAVE one item returned and I need ALL of the matching objects in the array return. However the second object that matches my query is being completely ignored.
This is what one of the items in the item collection looks like:
{
name: "soda",
cost: .50,
inventory: [
{ flavor: "Grape",
amount: 8 },
{ flavor: "Orange",
amount: 4 },
{ flavor: "Root Beer",
amount: 15 }
]
}
Here is the query I typed in to mongo shell:
Items.find({"inventory.amount" : { $lte : 10} } , { name : 1, "inventory.$.flavor" : 1})
And here is the result:
"_id" : ObjectId("59dbe33094b70e0b5851724c"),
"name": "soda"
"inventory" : [
{ "flavor" : "Grape",
"amount" : 8,
}
]
And here is what I want it to return to me:
"_id" : ObjectId("59dbe33094b70e0b5851724c"),
"name": "soda"
"inventory" : [
{ "flavor" : "Grape",
"amount" : 8
},
{ "flavor" : "Orange",
"amount" : 4
}
]
I'm new to mongo and am dabbling to get familiar with it. I've read through the docs but couldn't find a solution to this though it's quite possible I overlooked it. I'd really love some help. Thanks in advance.
first u can get your result by this query
db.Items.find({"inventory.amount" : { $lte : 10} } , { name : 1, "inventory.flavor" : 1 , "inventory.amount" : 1})
This question already has an answer here:
MongoDB: Checking if nested array contains sub-array
(1 answer)
Closed 5 years ago.
I have an an list of student which contain scores array of object, for example:
{
"_id" : ObjectId("58a6c4542d0de393d2739979"),
"student_id" : 0,
"scores" : [
{
"type" : "exam",
"score" : 76
},
{
"type" : "quiz",
"score" : 65
},
{
"type" : "homework",
"score" : 58
}
],
"class_id" : 438
}
I need to get student from collection, based on type and respective score with and condition for example
score greater than 60 in exam and
score greater than 50 in quiz and
score greater than 45 in homework
currently i'm trying the following query
db.students.find({$and: [{'scores.type': 'exam'}, {'scores.score': {$gt: 60}}]});
but its not working for single condition.
Any help greatly appreciated.
You can create query like this using $and and then create condition for each score type using $elemMatch and $gt
{
$and: [
{scores: {$elemMatch: {'type': 'exam','score': {$gt: 60}}}},
{scores: {$elemMatch: {'type': 'quiz','score': {$gt: 50}}}},
{scores: {$elemMatch: {'type': 'homework','score': {$gt: 45}}}}
]
}
i have 4 players with there scores in different matches.
e.g
{user: score} -- json keys
{'a': 10}, {'a':12}, {'b':16}
I am trying to find out a way in which i can found sum of single player using aggregation function.
users.aggregation([{$match:{'user':'a'}},{$group:{_id: null, scores:{$sum:'$score'}])
i am repeating same thing for b also and continue
In shot i am doing same thing for different users for too many times.
What is the best way or different way or optimize way, so i can write aggregate query once for all users
You can just match out the required users with the $in clause, and then group as #Sourbh Gupta suggested.
db.users.aggregate([
{$match:{'user':{$in: ['a', 'b', 'c']}}},
{$group:{_id: '$user', scores:{$sum:'$score'}}}
])
group the data on the basis of user. i.e.
users.aggregation([{$group:{_id: "$user", scores:{$sum:'$score'}}}])
Not too sure about your document structures, but if you've got 2 diffrent fields for 2 diffrent scores you can group together and sum then and then project and sum then 2 grouped sums (if that makes sense)
So for example, I have these docuemnts:
> db.scores.find()
{ "_id" : ObjectId("5858ed67b11b12dce194eec8"), "user" : "bob", "score" : { "a" : 10 } }
{ "_id" : ObjectId("5858ed6ab11b12dce194eec9"), "user" : "bob", "score" : { "a" : 12 } }
{ "_id" : ObjectId("5858ed6eb11b12dce194eeca"), "user" : "bob", "score" : { "b" : 16 } }
Notice we have a user bob and he has 2x a scores and 1x b score.
We can now write an aggregation query to do a match for bob then sum the scores.
db.scores.aggregate([
{ $match: { user : "bob" } },
{ $group: { _id : "$user", sumA : { $sum : "$score.a" }, sumB : { $sum : "$score.b" } } },
{ $project: { user: 1, score : { $sum: [ "$sumA", "$sumB" ] } } }
]);
This will give us the following result
{ "_id" : "bob", "score" : 38 }
This question already has answers here:
Select Max() with "group by" in mongodb
(4 answers)
Closed 6 years ago.
Imagine I have a MongoDB collection such as the following, where each row corresponds to a document:
{name:'rick', age:30}
{name:'john', age:40}
{name:'rick', age:35}
{name:'john', age:20}
{name:'jeff', age:50}
{name:'jeff', age:40}
Some documents have the "name" field set to the same value (2 ricks, 2 johns and 2 jeffs). If two or more documents have the "name" field set to the same value, of these I want to select only the document with the highest age. Like this:
{name:'rick', age:35}
{name:'john', age:40}
{name:'jeff', age:50}
Is there a rick aged 30 and a rick aged 35? I select rick aged 35! And so on...
But how can the query look like?
db.getCollection('Mytest').aggregate({$group:{_id:{"name":"$name"}, age: { $max: "$age" }}})
Output:
{
"_id" : {
"name" : "jeff"
},
"age" : 50
}
/* 2 */
{
"_id" : {
"name" : "john"
},
"age" : 40
}
/* 3 */
{
"_id" : {
"name" : "rick"
},
"age" : 35
}
db.collection.aggregate([{$group:{_id:"$name",sal:{$max:"$age"}}}]);