How to achieve this query in mongodb - mongodb

I am new in mongodb, my mysql query is:
select count(_id) as numberOfRecord,createdDate,orderId
from CakeOrder
where createdDate >= '2019-08-12' and createdDate <= '2019-10-12'
group by createdDate
order by createdDate desc
How I will convert this query to mongodb?
Date format is "createdDate" : ISODate("2019-10-12T07:12:36.390Z")

You can do this with MongoDB Aggregation Framework
here is mongo shell command for you:
db.getCollection("myCollection").aggregate(
[
{
"$match" : {
"$and" : [
{
"createDate" : {
"$gte" : ISODate("2019-01-01T00:00:00.000+0000")
}
},
{
"createDate" : {
"$lte" : ISODate("2019-01-01T00:00:00.000+0000")
}
}
]
}
},
{
"$group" : {
"_id" : "$createDate",
"count" : {
"$sum" : 1
}
}
},
{
"$sort" : {
"_id" : -1
}
}
]
);

Related

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 query to match date fails

Just can't get this seemingly simple query to work. All I want to do is match records that have a specific date range (the range could be 1 for the same date). Any insight is appreciated. I have verified the collection has documents with date = "2015-11-23T09:00:00.000Z".
db.getCollection('MyCollection').find(
{ "$and" :
[ { "name" : { "$in" : [ "Joe", "Jane"]}} ,
{ "date" : { "$gte" : { "$date" : "2015-11-23T09:00:00.000Z"} , "$lte" : { "$date" : "2015-11-23T09:00:00.000Z"}}}
]}
)
frostbite,
Just change your above query to:
db.getCollection('MyCollection').find(
{
"$and" :
[
{ "name" : { "$in" : [ "Joe", "Jane"]}} ,
{ "date" : {
"$gte" :ISODate("2015-11-23T09:00:00.000Z"),
"$lte":ISODate("2015-11-23T09:00:00.000Z")
}
]
})

How to perform count(column) in mongodb with aggregation?

I am trying to do to the equivalent of the following query in mongodb:
select count(*), count(category), sum(price) from sales group by usergender
Here is what the documents in my collection look like:
{
"_id" : ObjectId("54da8b0aa7c80aed4a9f9f33"),
"userincome" : "$100,000 - $200,000",
"county" : "Los Angeles",
"userstate" : "California",
"usercity" : "Los Angeles",
"price" : 100,
"category" : "Swimwear",
"usergender" : "Male"
}
Here is my aggregation which returns count(*) and sum(price) but I am not sure how to add in count(category).
db['stream.sales'].aggregate([
{
$group:{
_id:"$usergender",
price:{
$sum:"$price"
},
_count:{
$sum:1
}
}
}
])
I know I can run a separate aggregation to get count(category) but I would like to do it in aggregation, because I don't want all my results filtered where category exists = true.
db['stream.sales'].aggregate([
{
$match:{
'category':{
"$exists":true
}
}
},
{
$group:{
_id:"$usergender",
count:{
$sum:1
}
}
}
]);
Edit:
Was able to find the solution with the help of wdberkleys response:
db['stream.sales'].aggregate([
{ "$group" : {
"_id" : "$usergender",
"count" : { "$sum" : 1 },
"price" : { "$sum" : "$price" },
"category" : { "$push" : "$category" }
} },
{ "$project" : {
"count" : 1,
"size" : 1,
"categories" : { "$size" : "$category" }
} }
])
Push the categories to a set during the $group, then $project the size of the resulting set of categories:
db.stream.sales.aggregate([
{ "$group" : {
"_id" : "$usergender",
"count" : { "$sum" : 1 },
"price" : { "$sum" : "$price" },
"categories" : { "$addToSet" : "$category" }
} },
{ "$project" : {
"count" : 1,
"size" : 1,
"categories" : { "$size" : "$category" }
} }
])

Count statement in mongodb

I have the following mysql statement but I'd like to use it with spring mongodb driver for java. How to convert it? Have looked at aggregation but have no clue how to.
SELECT SUM(CASE WHEN CreatedTime BETWEEN ('7:00:00' AND '7:14:59') THEN 1 ELSE 0) as firstCount,
SUM(CASE WHEN CreatedTime BETWEEN ('7:15:00' AND '7:29:59') THEN 1 ELSE 0) as secondCount,
FROM MyTable
Where username='Jim'
Mongo document:
{ _id: ObjectId("5asd3ea3402984ca53"), username: "Jim", comment: "hi", CreatedTime: ISODate("2014-10-15T16:39:26.870Z") }
UPDATE on translating it to java using spring data:
When calling getTemplate().executeCommand(match); I get this:
{ "serverUsed" : "xxxxxxx" , "ok" : 0.0 , "errmsg" : "no such cmd: $match" , "bad cmd" : {
"$match" : { "username" : "Jim"} ,
"$group" : {
"firstCount" : {
"$sum" : {
"$cond" : {
"if" : {
"$and" : [ [ { "$gte" : { "$CreatedTime" : { "$date" : "2014-09-20T16:02:10.924Z"}}} , 1 , 0] ,
[ { "$lte" : { "$CreatedTime" : { "$date": "2014-10-20T15:48:19.744Z"}}} , 1 , 0]]} ,
"then" : { "$ifTrue" : 1} ,
"else" : { "$else" : 0}
}
}
}
}}}
Code that I use to get the JSON is here (its quite long).Query looks about the same that was suggested by #Wizard
What could be the trouble with $match? I read somewhere in Stackoverflow that old versions of mongodb do not support $match but I have Aug-2014 release so that can't be the case.
Like this:
db.MyTable.aggregate([{
$match : {
username : 'Jim'
}
}, {
$group : {
_id : 0,
firstCount : {
$sum : {
$cond : {
"if" : {
$and : [{
$gte : [ "$CreateTime", '7:00:00' ]
}, {
$lte : [ "$CreateTime", '7:14:59' ]
}]
},
"then" : 1,
"else" : 0
}
}
},
secondCount : {
$sum : {
$cond : {
"if" : {
$and : [{
$gte : [ "$CreateTime", '7:15:00' ]
}, {
$lte : [ "$CreateTime", '7:29:59' ]
}]
},
"then" : 1,
"else" : 0
}
}
},
}
}]);