Meteor - Mongo aggregate does not have $count stage [duplicate] - mongodb

This question already has answers here:
MongoDB SELECT COUNT GROUP BY
(9 answers)
Closed 6 years ago.
I am using meteorhacks:aggregate package to do Mongo aggregation in Meteor. I want to get the count at the last stage of the pipeline so I use this code:
Message.aggregate([
{
$match: {
// ...
}
}, {
$count: 'count'
}
]);
It is pretty simple and should work, but I only get this error:
Exception while invoking method 'methodname'
MongoError: Unrecognized pipeline stage name: '$count'
...
Please help, thanks.
Updated: this question is not duplicated as an editor suggested, my main intention is to find out why I can not use $count

$count is available in mongodb version 3.4. For previous versions,
you will need to use $group over a constant field.
Message.aggregate([
{
$match: {
// ...
}
}, {
$group: {
_id : null,
count : {$sum : 1}
}
}
]);

Related

Setting field2=field1 in MongoDB [duplicate]

This question already has answers here:
Update MongoDB field using value of another field
(12 answers)
Closed last year.
I am unable to update my document when I run
db.xx.updateOne({_id: ObjectId(""}, {$set: {lq: uq}) I get the error uncaught exception: ReferenceError: uq is not defined
uq field exists and contains integers, not sure why it don't work. Please help.
db.collection.update({
"_id": ObjectId("5a934e000102030405000000")
},
[
{
"$set": {
"field1": "$field2"
}
}
])
mongoplayground

Mongo Query in Nested Json Array [duplicate]

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 4 years ago.
A document in my collection looks like below:
{
"_id":"<uuid>",
"tests":[
{
"min":5,
"max":20
},
{
"min":15,
"max":35
}
]
}
Now, I want to find all the tests in which min >= 5.
db.coll.aggregate([
{ $match: { 'tests.min': {$gte : 5}} },
{ '$unwind': "$tests" }
]);
the above query somehow doesnt return the correct results.
You do not need to write a aggregate query for this. Use the $elemMatch operator for this. Your query will look like as shown
db.coll.find({
tests: {
$elemMatch: {
min: {
$gte: 5
}
}
}
})
The above query will return the desired result.
For more details visit
$elemMatch (query)

Find collection of highest value for pymongo [duplicate]

This question already has answers here:
Select Max() with "group by" in mongodb
(4 answers)
Closed 5 years ago.
With sample data in mongodb provided below,
data = [{'name':'a','value':2},
{'name':'a','value':3},
{'name':'b','value':1},
{'name':'b','value':3},
{'name':'c','value':2}]
I already know how to find one that matches the name 'a':
db.lol.find_one({'name': 'a']},sort=[("value", pymongo.DESCENDING)])
How can I get all the data for every name with the highest value, something like this, using pymongo:
data = [{'name':'a','value':3},
{'name':'b','value':3},
{'name':'c','value':2}]
db.lol.find_one({},sort=[("value", pymongo.DESCENDING)])
You can use simple $group with $max aggregation here:
db.lol.aggregate([
{
$group : {
_id : { name : '$name' },
value : { $max : '$value' }
}
},
{
$project : {
_id : 0,
value : 1,
name : "$_id.name"
}
}
]);

Save length of array in extra MongoDB field [duplicate]

This question already has answers here:
MongoDB: count the number of items in an array
(3 answers)
Closed 5 years ago.
According to this answer, I am trying to find out the size of an array and save it in the extra field.
I have a collection user_details and the document structure is something like :
{
user_id : 1,
likes : [1,2,3,4],
likes_count : 0
}
The query I'm using is as follows :
db.user_details.update({user_id : 1},{$set:{ likes_count : this.likes.length }})
BUT, it throws error that
"message" : "Cannot read property 'length' of undefined"
How do I save the length of an array in extra field?
PS: I'm using MongoDB 3.4
With MongoDB 3.4 and newer, you can use the $addFields pipeline to add the desired field ($addFields stage is equivalent to a $project stage that explicitly specifies all existing fields in the input documents and adds the new fields) and then write the result of the aggregate operation to the same collection using $out operator, thereby effectively updating the underlying collection.
If the collection specified by the $out operation already exists, then upon completion of the aggregation, the $out stage atomically replaces the existing collection with the new results collection.
To get the count, use the $size operator which returns the length of an array field. Bear in mind that all documents must have the likes field.
Overall, you need to run the following pipeline to achieve the desired update operation:
db.user_details.aggregate([
{ "$addFields": { "likes_count": { "$size": "$likes" } } },
{ "$out": "user_details" }
])
https://docs.mongodb.com/manual/reference/operator/aggregation/size/#exp._S_size
db.users.aggregate(
[
{
$project: {
likes_count: { $size: "$test" }
}
}
]
)
store the returned likes_count in an variable and perform update by providing the likes_count variable
something like this
Model.aggregate(
[
{
$project: {
likes_count: { $size: "$test" }
}
}
], (err, re) => {
console.log(err, re);
var likes_count = re[0].likes_count;
Model.update({email: 1}, {$set: {likes_count: likes_count}}, (err, d) => {
console.log(err, d);
})
}
)

MongoDB Aggregation Framework: $project: use a value of a doc as the name of a key [duplicate]

This question already has answers here:
count array occurrences across all documents with mongo
(2 answers)
Closed 7 years ago.
I have the following subdocument:
{
"id":1,
"url":"mysite.com",
"views":
[
{"ip":"1.1.1.1","date":"01-01-2015"},
{"ip":"2.2.2.2","date":"01-01-2015"},
{"ip":"1.1.1.1","date":"01-01-2015"},
{"ip":"1.1.1.1","date":"01-01-2015"}
]
}
and the following query so far:
db.collection.aggregate([
{
"$unwind": "$views"
},
{
"$group": {
"_id": "$views.ip",
"count": {
"$sum": 1
}
}
}
])
that returns the following result:
[
{
"_id":"2.2.2.2",
"count":1
},
{
"_id":"1.1.1.1",
"count":3
}
]
I would like to achieve the following output result, or quite similar:
[
{
"2.2.2.2": 1,
"1.1.1.1": 3
}
]
where each key would be every _id, and it's value their associated count. Is this possible to achieve?
I've tried so far adding at the end of the aggregate pipe a $project document like this one:
{
"$project": {
"_id": 0,
"$_id": "$count"
}
}
but it seems this doesn't work. Is there a way to achieve my desired query result or should I just stick to what I did so far and forget about it because it is not possible to achieve so?
The aggregation framework cannot output a key name from a value. The best place to do this in our application layer. As suggested in the comment, you could use either use the map reduce framework or forEach to achieve this, however, their performance is generally poorer, in particular in sharded environments, see the documentation.