Hi I am trying the below query in my nodejs code
const totalCount = await model.countDocuments({
'createdAt': { $gte: new Date(startDate), $lte: new Date(endDate) },
}).exec();
const activeCount = await model.countDocuments({
'createdAt': { $gte: new Date(startDate), $lte: new Date(endDate) },
'enabled': true,
}).exec();
const inactiveCount = (totalCount - activeCount);
return { totalCount, activeCount, inactiveCount };
Is there any way i can combine the above in a single query using aggregate in mongoose? Kindly guide me to the best solution .
Yes, quite simple using some basic operators, like so:
model.aggregate([
{
$match: {
createdAt: {
$gte: new Date(startDate),
$lte: new Date(endDate)
}
}
},
{
$group: {
_id: null,
totalCount: {
$sum: 1
},
activeCount: {
$sum: {
$cond: [
{
$eq: [
"$enabled",
true
]
},
1,
0
]
}
}
}
},
{
$project: {
_id: 0,
totalCount: 1,
activeCount: 1,
inactiveCount: {
$subtract: [
"$totalCount",
"$activeCount"
]
}
}
}
])
Mongo Playground
Related
I want to write a MongoDB query in NodeJS where it return the matching documents as well as the count of documents too. For ex consider the below code -
const result = await Student.aggregate(
[
{
$match: {
...filter
}
},
{
$project: {
_id: 1,
payment: 1,
type: 1,
BirthDate: 1
}
},
{
$sort: { StudentData: -1 }
},
{
$count: 'count'
},
{
$skip: skip
},
{
$limit: limit
}
]
);
Here I want to save two things in the result variable - the number of documents and individually all the documents.
let [{ totalItems, result }] = await Student.aggregate(
[
{
$match: {
...filter
}
},
{
$project: {
_id: 1,
payment: 1,
type: 1,
BirthDate: 1
}
},
{
$facet: {
result: [
{
$sort: { BirthDate: -1 },
},
{
$skip: skip
},
{
$limit: limit
}
],
totalItems: [{ $count: 'count' }]
}
},
{
$addFields: {
totalItems: {
$arrayElemAt: ["$totalItems.count", 0]
},
}
}
]
);
I have a code like this created with node.js and mongoose:
let data = { buy: [], sell: [] };
let buy = await Orders.aggregate([
{
$match: {
status: "Open",
instrument: instrument,
bidType: "buy",
},
},
{ $group: { _id: "$price", amount: { $sum: "$amount" } } },
{ $sort: { _id: -1 } },
{ $limit: 100 },
]);
I want to do this using springboot and mongodb. I tried many ways but couldn't.I will be
grateful if you could help me
I am trying to do a query between dates. In compass I can do the query without any problem using the native function ISODate(). But when trying in my code I can't import that function, and new Date() is not warking.
Documents as example:
let trxs = [{
_id:612e112f7a7eaa7a5c1fd0d3
created:2021-09-31T11:23:25.184+00:00
amount:19.98
user:"612e112f7a7eaa7a5c1fd0d1"
type:"deposit"
},
{
_id:612e112f7a7eaa7a5c1fd0d6
created:2021-09-31T11:23:25.184+00:00
amount:10
user:"612e112f7a7eaa7a5c1fd0d4"
type:"deposit"
}
]
Query
let trxs = await Transaction.aggregate([
{
$match: {
type: req.query.type,
$and: [
{
created:
{
$gt: new Date(new Date().setHours(0, 0, 0))
},
},
{
created:
{
$lt:new Date(new Date().setHours(23, 59, 59))
}
}
]
}
}, {
$group: {
_id: null,
amount: {
$sum: '$amount'
}
}
}
]);
//More info:
console.log(new Date(new Date().setHours(0, 0, 0))) // 2021-08-31T22:00:00.953Z
console.log(new Date(new Date().setHours(23, 59, 59))) // 2021-09-01T21:59:59.952Z
//Error
ReferenceError: amount is not defined
I tried to import ISODate function but I don't find the way to do it.
Try the moment.js library. There is no need for $and: []
{
$match: {
type: req.query.type,
created: {
$gt: moment().startOf('day').toDate(),
$lt: moment().endOf('day').toDate(),
}
}
}
I'm trying to make a query in my javascript code, when I try to execute the query it in robo3t it works, but when I try it in my angular code, it doesn't can you please help me?
Here is the code in robo3t.
db.getCollection('interviews').aggregate({
$match: {
status: {
$ne: 'Callback'
},
dateInserted: {
$gte: ISODate("2019-02-07 00:00:00"),
$lte: ISODate("2019-02-08 00:00:00")
},
'insertedBy.adminId': '5c353f840fe0fd000440df01'
}
},
{
$group: {
_id: {
insertedBy: '$insertedBy.email'
},
timeExported: {$first: '$dateInserted'},
total: {
$sum: 1
}
},
},
{
$limit: 100
}
)
and the result shows:
result image
Now here is my code in angular
query = [{
$match: {
status: {
$ne: 'Callback'
},
dateInserted: {
$gte: new Date("2019-02-07 00:00:00").toISOString(),
$lte: new Date("2019-02-08 00:00:00").toISOString()
},
'insertedBy.adminId': localStorage.getItem('_lgu_')
}
},
{
$group: {
_id: {
insertedBy: '$insertedBy.email'
},
timeExported: {$last: '$dateInserted'},
total: {
$sum: 1
}
},
},
{
$limit: 100
},
{
$sort: {
total: 1
}
}
]
Now when I try the query in angular, it doesn't give any result and when I remove the date condition:
dateInserted: {
$gte: new Date("2019-02-07 00:00:00").toISOString(),
$lte: new Date("2019-02-08 00:00:00").toISOString()
},
It will give a result but not what I am expecting.
My application needs to get the result of this query (this is already giving the correct result in mongoDb):
var denominator = db.getCollection('Transactions').aggregate({
$group: {
"_id": null,
"Alltotal": {$sum:"$transAmount"}
}
};
db.getCollection('Transactions').aggregate([{
$group: {
_id: '$merchantCode',
total: {
$sum: { $multiply: ['$transAmount', 100 ]}
}}},
{ $project: {
percentage: {
$divide: [
"$total",
denominator.toArray()[0].Alltotal
]
}
}
}
])
Now here is how I am trying to execute it:
var express = require('express');
var app = express();
var mongojs = require('mongojs');
var dbTransaction = mongojs('dataAnalysisDb',['Transactions']);
app.get('/Transactions',function(req,res){
var denominator = dbTransaction.Transactions.aggregate([{
$group: {
_id: 'null',
total: { $sum: '$transAmount' }
}
}]);
dbTransaction.Transactions.aggregate([{
$group: {
_id: '$mtype',
total: {
$sum: { $multiply: ['$transAmount', 100 ]}
}}},
{ $project: {
percentage: {
$divide: [
"$total",
denominator.toArray()[0].total
]
}
}
},
{ $sort : { _id : 1, posts: 1 } }
], function(err,docs){
console.log(docs); //this is for testing
res.json(docs);
});
});
I think this is not working because I am not sending the variable in the correct way to the server and when I use it on the operation it is not defined. I will appreciate any suggestion on how to fix it.
Thank you
I found a way to solve it and it might not be the best but it worked, I leave it here for whoever else needs it
var denominator = dbTransaction.Transactions.aggregate([{
$group: {
"_id": null,
"Alltotal": {$sum:"$transAmount"}
}}]).toArray(function(err,items){
console.log(items[0].Alltotal); //this is for testiong
dbTransaction.Transactions.aggregate([{
$group: {
_id: '$mtype',
total: {
$sum: { $multiply: ['$transAmount', 100 ]}
}}},
{ $project: {
percentage: {
$divide: [
"$total",
items[0].Alltotal
]
}
}
},
{ $sort : { _id : 1, posts: 1 } }
],function(err,docs){
console.log(docs); //this is for testing
res.json(docs);
});
});