Get count of a Local field with $lookup mongodb - mongodb

I want to get the count of local field specific projectId vise.For example i have below documents:
{
"_id" : ObjectId("5c0a4efa91b5021228681f7a"),
"projectId" : ObjectId("5c0a4083753a321c6c4ee024"),
"hours" : 8,
"__v" : 0
}
{
"_id" : ObjectId("5c0a4f4191b5021228681f7c"),
"projectId" : ObjectId("5c0a2a8897e71a0d28b910ac"),
"hours" : 6,
"__v" : 0
}
{
"_id" : ObjectId("5c0a4f4191b5021228681f7d"),
"projectId" : ObjectId("5c0a4083753a321c6c4ee024"),
"hours" : 2,
"__v" : 0
}
Now, I want to get the hours field count of projectId equals to 5c0a4083753a321c6c4ee024, which is 10.
Is it possible with $lookup?

$lookup is used to join two collections. And here you trying to get total counts of hours for the specific projectId. Therefore, you need to use $group here.
db.collection.aggregate([
{ "$match": { "projectId": mongoose.Types.ObjectId("5c0a4083753a321c6c4ee024") }}
{ "$group": {
"_id": "$projectId",
"totalHours": { "$sum": "$hours" }
}}
])

Related

How to limit number of returned objects in group query

I have a Mongodb database with several hundred records, each with a value for the field "pauseTime." I would like to count the number of records for each value of pauseTime. But I want to limit the query to the documents where pauseTime greater than 50 and less than 150.
I got so far as counting the number of each each value for pauseTime.
This is a record of the database:
{
"_id" : ObjectId("5ca74a95a094b08e97bd1278"),
"duration" : NumberInt(857),
"videoUrl" : "https://vimeo.com/3766858",
"pauseTime" : NumberInt(493),
"contentType" : "Comment",
"comment" : "vsvdbdbdab adb",
"__v" : NumberInt(0)
}
This is my query so far:
db.getCollection("videocomments").aggregate([ {"$group" : {_id:"$pauseTime", count:{$sum:1}}} ])
It returns:
{ "_id" : 480, "count" : 8 }
{ "_id" : 437, "count" : 5 }
{ "_id" : 51, "count" : 4 }
{ "_id" : 434, "count" : 4 }
{ "_id" : 750, "count" : 9 }
...
How do I proceed to limit the "_id" (i.e., pauseTime) to 50 < x < 150?
Use $lte and $gte query operator with the pauseTime
db.getCollection("videocomments").aggregate([
{ "$match": {
"pauseTime": { "$gte": 50, "$lte": 150 }
}},
{ "$group": {
"_id": "$pauseTime",
"count": { "$sum": 1 }
}}
])

mongodb aggregation $max and corresponding timestamp

I'm being challenged by the $group $max in an aggregation with MongoDB on Nodes Express app. Here is the a sample of the collection;
{"_id":"5b7e78cf022be03c35776bec",
"humidity":60,
"pressure":1014.18,
"temperature":26.8,
"light":2464,
"timestampiso":"2018-08-23T09:05:19.112Z",
"timestamp":1535015119112
},
{
"_id":"5b7e7892022be03c35776bea",
"humidity":60.4,
"pressure":1014.14,
"temperature":26.7,
"light":2422,
"timestampiso":"2018-08-23T09:04:18.115Z",
"timestamp":1535015058115
},
{
"_id":"5b7e7855022be03c35776be8",
"humidity":60.6,
"pressure":1014.2,
"temperature":26.6,
"light":2409,
"timestampiso":"2018-08-23T09:03:17.113Z",
"timestamp":1535014997113
}]
What I'm trying to do is to query the collection, by first retrieving the entries of the last hour based on the timestamp and then looking for highest pressure of the sample (should be 60 entries as there is one entry per minute)
What I can de is find this value. What I'm stuggling on to have the timestamp related to that max value.
When I run
db.collection("ArduinoSensorMkr1000").
aggregate([{ "$match" : {"timestamp" : {"$gte" : (Date.now()-60*60*1000)}}},
{ "$group" : {"_id" : null, maxpressure : {"$max" : "$pressure"}
}
},
{
"$project" : { "_id" : 0 }
}
])
Fine, the output is correct and I get the maxpressure as so
[{"maxpressure":1014.87}]
but what I'm trying to output is the maxpressure field but with it, its corresponding timestamp. The output should look as so
[{"maxpressure":1014.87,"timestamp":1535015058115}]
Any hints on how I get this timestamp value to show?
Thank you for your support
You can try this first need to sort your data using $sort and you can pick max value by using $first
QUERY
db.col.aggregate([
{ "$match": { "timestamp": { "$gte": (Date.now() - 60 * 60 * 1000) } } },
{ "$sort": { "pressure": -1 } },
{
"$group": {
"_id": null, "maxpressure": { "$first": "$pressure" },
"timestamp": { "$first": "$timestamp" }
}
},
{
"$project": { "_id": 0 }
}
])
DATA
[{
"_id" : "5b7e78cf022be03c35776bec",
"humidity" : 60.0,
"pressure" : 1014.18,
"temperature" : 26.8,
"light" : 2464.0,
"timestampiso" : "2018-08-23T09:05:19.112Z",
"timestamp" : 1535015119112.0
},
{
"_id" : "5b7e7892022be03c35776bea",
"humidity" : 60.4,
"pressure" : 1014.14,
"temperature" : 26.7,
"light" : 2422.0,
"timestampiso" : "2018-08-23T09:04:18.115Z",
"timestamp" : 1535015058115.0
},
{
"_id" : "5b7e7855022be03c35776be8",
"humidity" : 60.6,
"pressure" : 1014.2,
"temperature" : 26.6,
"light" : 2409.0,
"timestampiso" : "2018-08-23T09:03:17.113Z",
"timestamp" : 1535014997113.0
}]
THE OUTPUT
{
"maxpressure" : 1014.87,
"timestamp" : 1535015058115.0
}
My suggestion is to use sort/limit instead of grouping. By this way you can get entire document before project only interesting fields :
db['ArduinoSensorMkr1000'].aggregate(
[{ "$match" : {"timestamp" : {"$gte" : (Date.now()-5*60*60*1000)}}},
{$sort:{pressure:-1}},
{$limit:1},{
"$project" : { "_id" : 0,"timestamp":1,"pressure":1 }}
])

Slow $group in mongodb

I am working to fetch data from mongodb using $group. I have modified my query to
db.mydata.aggregate([{ $match: {"CreatedOn": {$lte: ISODate("2015-10-27T03:45:09Z"),
"$gte": ISODate("2015-09-09T07:37:27.526Z")}} },
{"$group" : { "_id" : "$myIP" , "total" : { "$sum" : "$SuccessCount"}}},
{ "$project" : { "myIP" : "$_id" , "_id" : 0 , "Total" : "$total"}},
{ "$sort" : { "Total" : -1}}, { "$limit" : 10}])
But it is taking more than 2 minute to execute, even for small amount of data. I have created index for CreatedOn. I have also created index for myIP.
I have document structure like
{ "_id" : ObjectId("55d33d7045cedc287ed840a3"),
"myIP" : "10.10.10.1","SuccessCount" : 1,
"CreatedOn":ISODate("2015-10-27T03:45:09Z")
}
I want success count's by all myIP's with maximum on top.

MongoDB $ne in sub documents

{
"_id" : ObjectId("53692eb238ed04c824679f18"),
"firstUserId" : 1,
"secondUserId" : 17,
"messages" : [
{
"_id" : ObjectId("5369338997b964b81d579fc6"),
"read" : true,
"dateTime" : 1399403401,
"message" : "d",
"userId" : 1
},
{
"_id" : ObjectId("536933c797b964b81d579fc7"),
"read" : false,
"dateTime" : 1399403463,
"message" : "asdf",
"userId" : 17
}
]
}
I'm trying to select all documents that have firstUserId = 1 and also have sub documents
that have userId differnet ($ne) to 1 and read = false.
I tried:
db.usermessages.find({firstUserId: 1, "messages.userId": {$ne: 1}, "messages.read": false})
But it returns empty cause messages have both 1 and 17.
And also how to count subdocuments that have given case?
Are you trying to get the count of all the documents which are returned after your match criteria? If Yes, then you might consider using aggregation framework. http://docs.mongodb.org/manual/aggregation/
Something like below could be done to get you the counts:
db.usermessages.aggregate(
{ "$unwind": "$messages" },
{ "$match":
{ "firstUserId": 1,
"messages.userId": { "$ne" : 1},
"messages.read": false
}
},
{ "$group": { "_id" :null, "count" : { "$sum": 1 } } }
)
Hope this helps.
PS: I have not tried this on my system.

MongoDB: How can I calculate total count without using $group operator

I have following result:
"result" : [
{
"_id" : "London",
"count" : 499
},
{
"_id" : "Paris",
"count" : 135
},
{
"_id" : "Lviv",
"count" : 95
}
]
And here is query:
{"$group":{
_id: "$city",
"count" : {"$sum":1}
}
}
So, I want some how to calculate all fields not only grouped. I think it would better to show expected result:
"result" : [
{
"_id" : "London",
"count" : 499,
"total" : 729
},
{
"_id" : "Paris",
"count" : 135,
"total" : 729
},
{
"_id" : "Lviv",
"count" : 95,
"total" : 729
}
]
Expected result has "total" field which calculated as amount of "count" field (499+135+95 = 729).
EDITED: I must use only aggregation framework!
Can someone help me with this?
You have to count the total number before:
db.coll.count( ..., function( err, total ) {
and then use that result in your aggregation command:
{
"$group": {
_id: "$city",
count: { "$sum": 1 },
total: total
}
EDIT:
If you only want to use aggregation framework, try this instead of db.coll.count():
{
"$group": {
_id: 1,
count: { "$sum": 1 }
}
}
Sounds like db.collection.count() would give you your result actually. This is because you are actually just summing up ALL documents in the collection there.