Need to add a "generated value" to the results in MongoDB - mongodb

I have a query
[ { "$match" : { "vm_id" : "218276"}},{ "$group" : { "_id" : { "$dayOfMonth" : "$ts"} , "public_tx_total" : { "$sum" : "$interface_public_tx_bytes"} , "public_rx_total" : { "$sum" : "$interface_public_rx_bytes"} , "private_tx_total" : { "$sum" : "$interface_private_tx_bytes"} , "private_rx_total" : { "$sum" : "$interface_private_rx_bytes"} , "count" : { "$sum" : 1}}},{ "$sort" : { "_id" : 1}} ]
where I want to add a key that takes $ts and pulls the year out of and add it to the results
year: {$year: "$ts"}
I 'm not sure where to place the snippet without causing an error.

You can do it by adding the following command into the group query.
"year" : {$first : { $year:"$ts"}}
Your query will look like :
[
{"$match":{"vm_id":"218276"}},
{"$group":{"_id":{"$dayOfMonth":"$ts"},
"year":{$first:{$year:"$ts"}},
"public_tx_total":{"$sum":"$interface_public_tx_bytes"},
"public_rx_total":{"$sum":"$interface_public_rx_bytes"},
"private_tx_total":{"$sum":"$interface_private_tx_bytes"},
"private_rx_total":{"$sum":"$interface_private_rx_bytes"},
"count":{"$sum":1}}},
{"$sort":{"_id":1}}
]

Related

ISODate in MongoDB query with double quotes

I'm trying to make a MongoDB query, here's how I'm trying to do, part of my query:
db.admin_25c6b5.aggregate(
[
{ "$match" : { "attr" : "temperature", "ts" : {"$gte" : ISODate("2015-01-01"), "$lt" : ISODate("2025-01-01") } } },
{ "$sort" : { "ts" : 1 } },
{ "$project" : { "value" : 1, "_id" : 0 } }
])
When I tried this on Robo 3T it worked, but not on Grafana, it gave me the message Unexpected token I in JSON at position 63, the ISODate didn't work.
Then, I tried to add quotes:
db.admin_25c6b5.aggregate(
[
{ "$match" : { "attr" : "temperature", "ts" : {"$gte" : "ISODate("2015-01-01")", "$lt" : "ISODate("2025-01-01")" } } },
{ "$sort" : { "ts" : 1 } },
{ "$project" : { "value" : 1, "_id" : 0 } }
])
The new error message is: Unexpected number in JSON at position 73
I tried using this, but it didn't work:
db.admin_25c6b5.aggregate(
[
{ "$match" : { "attr" : "temperature", "ts" : {"$gte" : "ISODate(\"2015-01-01\")", "$lt" : "ISODate(\"2025-01-01\")" } } },
{ "$sort" : { "ts" : 1 } },
{ "$project" : { "value" : 1, "_id" : 0 } }
])
The new error message is Unexpected end of JSON input
I think the problem is that I am trying to use double quotes inside double quotes, do you have any idea to solve this?

Mongo aggregation groups and subgroup

Hi I have a Mongo aggregation:
[
{
"$match" : {
"dateTime" : {
"$gte" : ISODate("2017-01-01T00:00:00.000+0000"),
"$lt" : ISODate("2018-01-01T00:00:00.000+0000")
}
}
},
{
"$group" : {
"_id" : "dateTime",
"totals" : {
"$sum" : "$payment.totalAmount"
},
"count" : {
"$sum" : 1.0
}
}
}
],
{
"allowDiskUse" : false
}
);
This works fine. It aggregates, and sums by date range I supplied and I get an output as follows.
{
"_id" : "dateTime",
"totals" : 2625293.825017198,
"count" : 12038.0
}
However, I also want to further refine the groupings.
I have a field called 'companyId' and I want to calculate the sum and count by each company Id for the given time range.
I would like to get an output similar to this, where I get a sum and count for each company ID in the date range I queried, not just a sum/count of all the data:
[
{
"companyId" : "Acme Co",
"totals" : 2625293.825017198,
"count" : 12038.0
},
{
"companyId" : "Beta Co",
"totals" : 162593.82198,
"count" : 138.0
},
{
"companyId" : "Cel Co",
"totals" : 593.82,
"count" : 38.0
}
]
How do I do this? I have not been able to find a good example online.
Thanks

left join in mongodb not working

Below Query, we are using for fetching the data, how to convert this to as left join Query.
so if id column does not exist in a user_content table the value of count would be 0.
db.contents.aggregate([
{ "$lookup" : {
"from" : "user_content" ,
"localField" : "_id" ,
"foreignField" : "contentId" ,
"as" : "user_content"}
} ,
{ "$unwind" : {
"path" : "$user_content" ,
"preserveNullAndEmptyArrays" : true}
} ,
{ "$match" : { "user_content.liked" : true}} ,
{ "$group" : {
"_id" : "$_id" ,
"popularity" : {
"$first" : "$popularity"} ,
"user_content" : { "$push" : "$user_content"}
}
} ,
{ "$project" : {
"popularity" : 1 ,
"count" : { "$size" : [ "$user_content"]}}
} ,
{ "$skip" : 0} ,
{ "$limit" : 1000000}
]);

MongoDB, Grouping by Multiple Fields

pretty new to Mongo and am finding some simple things that i would do in SQL frustratingly difficult in Mongo.
I have an object similar to this below
[{
"_id" : ObjectId("5870fb29a1fe030e1a2909db"),
"updatedAt" : ISODate("2017-01-07T14:28:57.224Z"),
"createdAt" : ISODate("2017-01-07T14:28:57.224Z"),
"state" : "Available",
},
{
"_id" : ObjectId("5870fb29a1fe030e1a2909dc"),
"updatedAt" : ISODate("2017-01-07T14:28:57.224Z"),
"createdAt" : ISODate("2017-01-07T14:28:57.224Z"),
"state" : "notReady",
},
{
"_id" : ObjectId("5870fb29a1fe030e1a2909d9"),
"updatedAt" : ISODate("2017-01-07T14:28:57.224Z"),
"createdAt" : ISODate("2017-01-07T14:28:57.224Z"),
"state" : "Disconnected",
}]
What i'm looking to do it group the data by the Maximum date and the state.
Ideally the result i would be looking for would be something like the following.
{
latestDate: "2017-01-07T14:28:57",
states : {
available : 10,
disconnected : 5,
notReady : 2
}}
Basically i'm looking for the SQL equivalent of this:
SELECT createdAt, state, COUNT(rowid)
FROM db
WHERE date = (SELECT MAX(createdAt) FROM db)
GROUP BY 1,2
I've searched around here and have found some good info but am probably missing something straight forward. Ive only managed to get here so far
db.collection.aggregate([
{$project: {"_id" : 0,"state": 1, "date" : "$createdAt"}},
{$group : {"_id" : {"date":"$date", "state": "actual"}, "count":{"$sum":1}}}
])
Any help would be appreciated :)
db.collection.aggregate([
{
$group : {
_id : {
date : "$createdAt",
state : "$state"
},
count : {$sum : 1}
}
},
{
$group : {
_id : "$_id.date",
states : {
$addToSet : {
state : "$_id.state",
count : "$count"
}
}
}
},
{
$sort : {_id : -1}
},
{
$limit : 1
},
{
$project : {
_id : 0,
latestDate : "$_id",
states : "$states"
}
}
])
output :
{
"latestDate" : ISODate("2017-01-07T14:28:57.224Z"),
"states" : [
{
"state" : "Available",
"count" : 1
},
{
"state" : "notReady",
"count" : 1
},
{
"state" : "Disconnected",
"count" : 1
}
]
}

Mongodb sort by sum of keys

I have a json document
{
{
"_id" : ObjectId("5715c4bbac530eb3018b456a"),
"content_id" : "5715c4bbac530eb3018b4569",
"views" : NumberLong(200),
"likes" : NumberLong(100),
"comments" : NumberLong(0)
},
{
"_id" : ObjectId("5715c4bbac530eb3018b4568"),
"content_id" : "5715c4bbac530eb3018b4567",
"views" : NumberLong(300),
"likes" : NumberLong(200),
"comments" : NumberLong(0)
},
{
"_id" : ObjectId("5715c502ac530ee5018b4956"),
"content_id" : "5715c502ac530ee5018b4955",
"views" : NumberLong(500),
"likes" : NumberLong(0),
"comments" : NumberLong(200)
}
}
How can we sort the document order by SUM("views", "likes", "comments")
something like in mysql
SELECT SUM(key1, key2, key3) AS key
FROM document
ORDER BY key
Thanks in advance.
First do a projection to obtain the sum of all the likes, views and comments, then sort based on that sum. I am considering group by content_id if is needed in the second snippet
db.test.aggregate([
{ $project : { "_id" : "$content_id", "total" : { $add : [ "$likes", "$views", "$comments"]}}},
{ $sort : { "total" : 1 }}
])
If you need a group operation if content_id can be duplicated
db.test.aggregate([
{ $project : { "_id" : "$content_id", "total" : { $add : [ "$likes", "$views", "$comments"]}}},
{ $group : { "_id" : "$_id" , totalPerId : { $sum : "$total" }}},
{ $sort : { "total" : 1 }}
])
Based on your test data, you will get:
{ "_id" : "5715c502ac530ee5018b4955", "totalPerId" : NumberLong(700) }
{ "_id" : "5715c4bbac530eb3018b4567", "totalPerId" : NumberLong(500) }
{ "_id" : "5715c4bbac530eb3018b4569", "totalPerId" : NumberLong(300) }