how to get all fields in the query - javascript

I am trying in this aggregation is working but not get all fields how to get all fields any suggestion me i wright any wrong this query please check
db.lights.aggregate({
$match: {
CREATE_DATE: {
$gte: ISODate("2018-01-24T20:05:30.000Z"),
$lt: ISODate("2018-02-24T20:05:30.000Z")
}
}
}, {
$addFields: {
offduration: {
$divide: [{
$subtract: ["$RECEIVEDDATE", "$CREATE_DATE"]
}, 3600000]
}
}
}, {
"$group": {
_id: {
SWITCHID: "$SWITCHID",
STATUS: "$STATUS"
},
avgduration: {
$avg: "$offduration"
}
}
}, {
$project: {
_id: 1,
SWITCHID: 1,
CREATE_DATE: 1,
RECEIVEDDATE: 1,
STATUS: 1,
avgduration: '$avgduration',
offduration: '$offduration'
}
})

try this,
db.lights.aggregate({
$match: {
CREATE_DATE: {
$gte: ISODate("2018-01-24T20:05:30.000Z"),
$lt: ISODate("2018-02-24T20:05:30.000Z")
}
}
}, {
$addFields: {
offduration: {
$divide: [{
$subtract: ["$RECEIVEDDATE", "$CREATE_DATE"]
}, 3600000]
}
}
}, {
"$group": {
_id: {
SWITCHID: "$SWITCHID",
STATUS: "$STATUS"
},
avgduration: {
$avg: "$offduration"
},
SWITCHID: {
$first: "$SWITCHID"
},
CREATE_DATE: {
$first: "$CREATE_DATE"
},
RECEIVEDDATE: {
$first: "$RECEIVEDDATE"
},
STATUS: {
$first: "$STATUS"
},
offduration: {
$first: "$offduration"
},
}
}, {
$project: {
_id: 1,
SWITCHID: 1,
CREATE_DATE: 1,
RECEIVEDDATE: 1,
STATUS: 1,
avgduration: '$avgduration',
offduration: '$offduration'
}
})
You can use $$ROOT also, It'll add entire object inside data. You have to refer using data.key
{
$group: {
_id: {
SWITCHID: "$SWITCHID",
STATUS: "$STATUS"
},
data: {
$first: "$$ROOT"
}
}
}

Related

Mongo DB query to return count?

I have two collections Course and File.
This is my data from Course collection
[{
_id: 1,
name: "Course1",
price: "100"
},
{
_id: 2,
name: "Course2",
price: "200"
}]
This is my data from files collection
[{
_id: 1,
name: "File1",
isFree: true,
courseId: 1
}
{
_id: 2,
name: "File2",
isFree: false,
courseId: 1
}
{
_id: 3,
name: "File3",
isFree: false,
courseId: 1
}]
I want to retrieve Course 1 with Course name,Count of files which are free,Count of files which are not free.
My attempt:
Course.aggregate([
{$lookup:{
from:"files",
localField: "_id",
foreignField: "courseId",
as: "files"
}},
])
This is my response If I execute my above query:
[
{
"_id": "6161bdcc0aada09d81598840",
"name": "Course1",
"files": [
{
"_id": "6166a0814ad3f56b71232b9c",
"name": "File1.jpeg",
"isFree":true
},
{
"_id": "6166a0814ad3f56b71232b9d",
"name": "File2.jpeg",
"isFree":false
},
{
"_id": "6166a0814ad3f56b71232b9v",
"name": "File3.jpeg",
"isFree":false
}
]
}
]
I want my output as:
[
{
"_id": "6161bdcc0aada09d81598840",
"name": "Course1",
"files": {"free": 1,"paid": 2}
}
]
You can try lookup with pipeline,
$lookup with pipeline, pass courseId in let
$match courseId condition
$group by isFeee and get total count
$project to show required fields in k(key) and v(value) format
$cond to check if isFree true then return "free" otherwise return "paid"
$addFields to update files array
$arrayToObject convert files key-value array to an object
$ifNull to check if property is not exists then set 0
await Course.aggregate([
{
$lookup: {
from: "files",
let: { courseId: "$_id" },
pipeline: [
{ $match: { $expr: { $eq: ["$$courseId", "$courseId"] } } },
{
$group: {
_id: "$isFree",
count: { $sum: 1 }
}
},
{
$project: {
_id: 0,
k: { $cond: ["$_id", "free", "paid"] },
v: "$count"
}
}
],
as: "files"
}
},
{
$addFields: {
files: { $arrayToObject: "$files" }
}
},
{
$addFields: {
"files.free": { $ifNull: ["$files.free", 0] },
"files.paid": { $ifNull: ["$files.paid", 0] }
}
}
])
Playground
Try following:
db.course.aggregate([
{
$lookup: {
from: "files",
localField: "_id",
foreignField: "courseId",
as: "files",
},
},
{
$unwind: {
path: "$files",
preserveNullAndEmptyArrays: true,
},
},
{
$group: {
_id: "$_id",
name: {
$first: "$name",
},
price: {
$first: "$price",
},
free: {
$sum: {
$cond: [
{
$eq: ["$files.isFree", true],
},
1,
0,
],
},
},
paid: {
$sum: {
$cond: [
{
$eq: ["$files.isFree", false],
},
1,
0,
],
},
},
},
},
{
$addFields: {
"files.free": "$free",
"files.paid": "$paid",
},
},
{
$project: {
_id: 1,
name: 1,
files: 1,
price: 1,
},
},
]);

How to get number of registered users each month with MongoDB query?

I am trying to retrieve the total number of users registered each month grouping them by year and month they registered in MongoDB
My user model looks like this
email: String,
gender: String,
password: {
hash: {
type: String,
// required: true
},
salt: {
type: String,
// required: true
},
reset: {
id: {
type: String,
default: "",
},
code: {
type: String,
default: "",
},
},
},
name: {
first: String,
last: String,
username: String,
},
date: {
registered: {
type: Date,
}
}
The date parameter is an ISO string
the query that I tried is this
var today = new Date();
data.newUsersEachMonth=await AccountModel.aggregate([
{ "$match": {
"date": {"date.registered": { "$lt": today.toISOString() }}
}},
{ "$group": {
"_id": {
"year": { "$year": "$date" },
"month": { "$month": "$date" },
},
"count": { "$sum": 1 }
}}
])
But it returns an empty array How can i solve this?
UPDATE
As suggested i tried these two queries
{ "$match": {
"date.registered": { "$lt": today.toISOString() }
}},
{ "$group": {
"_id": {
"year": { "$year": "$date.registered" },
"month": { "$month": "$date.registered" },
},
"count": { "$sum": 1 }
}}
])
and
data.newUsersEachMonth=await AccountModel.aggregate([
{ "$match": {
"date.registered": { "$lt": today.toISOString() }
}},
{ "$group": {
"_id": {
"year": { "$year": "$date" },
"month": { "$month": "$date" },
},
"count": { "$sum": 1 }
}}
])```
Still getting an empty array
Aggregation query should be like below,
[
{
'$match': {
'date.registered': {
'$lt': today.toISOString()
}
}
},
{
'$project': {
'month': {
'$month': '$date.registered'
},
'year': {
'$year': '$date.registered'
}
}
}, {
'$group': {
'_id': {
'month': '$month',
'year': '$year'
},
'total': {
'$sum': 1
},
'month': {
'$first': '$month'
},
'year': {
'$first': '$year'
}
}
}
]

how to get all fields in the query with aggregation

i am trying this aggregation i got the exact out put but not get all fields please solve my problem how to get all fields in following query
db.lights.aggregate({ $match: { CREATE_DATE: { $gte: ISODate("2018-01-24T20:05:30.000Z"), $lt: ISODate("2018-02-24T20:05:30.000Z") } } }, { $addFields: { offduration: { $divide: [{ $subtract: ["$RECEIVEDDATE", "$CREATE_DATE"] }, 3600000] } } }, { "$group": { _id: { SWITCHID: "$SWITCHID", STATUS: "$STATUS" }, avgduration: { $avg: "$offduration" }, SWITCHID: { $first: "$SWITCHID" }, CREATE_DATE: { $first: "$CREATE_DATE" }, RECEIVEDDATE: { $first: "$RECEIVEDDATE" }, STATUS: { $first: "$STATUS" }, offduration: { $first: "$offduration" }, } }, { $project: { _id: 0, SWI`TCHID: 1, CREATE_DATE: 1, RECEIVEDDATE: 1, STATUS: 1, avgduration: '$avgduration', offduration: '$offduration' } },{"$group" : { _id: { SWITCHID: "$SWITCHID" }, on_minus_off: { $sum:{ "$cond": [ { "$eq": ["$STATUS", "LIGHTS OFF"] }, "$avgduration", { $subtract: [ 0, "$avgduration" ] } ]}} }})

how to write the single aggregation in the query

I am writing the first query greater than equal to CREATE_DATE and less then CREATE_DATE I got the answer ofter calculate the duration write another query but how to write the single query in the aggregation.
Query 1
db.lights.aggregate({
$match: {
CREATE_DATE: {
$gte: ISODate("2018-01-24T20:05:30.000Z"),
$lt: ISODate("2018-02-24T20:05:30.000Z")
}
}
});
Result
{
"_id": ObjectId("5a9a74843711955836a8b4b5"),
"SWITCHID": "Z4-W40-SS451A/4",
"CREATE_DATE": ISODate("2018-01-24T20:05:30Z"),
"RECEIVEDDATE": ISODate("2018-02-24T20:05:45Z"),
"STATUS": "LIGHTS ON"
}
Query 2
db.lights.aggregate([
{
$addFields: {
offduration: {
$divide: [
{
$subtract: [
"$RECEIVEDDATE",
"$CREATE_DATE"
]
},
3600000
]
}
}
}
]);
Result
{
"_id": ObjectId("5a9a75af3711955836a8b4c8"),
"SWITCHID": "Z4-W40-SS451A/5",
"CREATE_DATE": ISODate("2018-02-24T20:05:30Z"),
"RECEIVEDDATE": ISODate("2018-02-24T20:05:45Z"),
"STATUS": "LIGHTS ON",
"offduration": 0.004166666666666667
}
You need to improve your query like this :
db.lights.aggregate({
$match: {
CREATE_DATE: {
$gte: ISODate("2018-01-24T20:05:30.000Z"),
$lt: ISODate("2018-02-24T20:05:30.000Z")
}
}
},
{
$addFields: {
offduration: {
$divide: [
{
$subtract: [
"$RECEIVEDDATE",
"$CREATE_DATE"
]
},
3600000
]
}
}
},
{
$project: {
_id: 1,
SWITCHID: 1,
CREATE_DATE: 1,
RECEIVEDDATE: 1,
STATUS: 1,
offduration: '$offduration',
avgduration: { $avg: "$offduration" }
}
});

how to write the single query in the aggregation

i am trying this aggregation but how to write single query in this aggregations how to solve the questions. please suggest me .please suggest me two documents switchID are same . but STATUS different one STATUS IS :LIGHTS OFF another STATUS IS:LIGHTS ON . any possible add the query LIGHTS OFF avgduration - LIGHTS ON avgduration
db.lights.aggregate({
$match: {
CREATE_DATE: {
$gte: ISODate("2018-01-24T20:05:30.000Z"),
$lt: ISODate("2018-02-24T20:05:30.000Z")
}
}
}, {
$addFields: {
offduration: {
$divide: [{
$subtract: ["$RECEIVEDDATE", "$CREATE_DATE"]
}, 3600000]
}
}
}, {
"$group": {
_id: {
SWITCHID: "$SWITCHID",
STATUS: "$STATUS"
},
avgduration: {
$avg: "$offduration"
},
SWITCHID: {
$first: "$SWITCHID"
},
CREATE_DATE: {
$first: "$CREATE_DATE"
},
RECEIVEDDATE: {
$first: "$RECEIVEDDATE"
},
STATUS: {
$first: "$STATUS"
},
offduration: {
$first: "$offduration"
},
}
}, {
$project: {
_id: 1,
SWITCHID: 1,
CREATE_DATE: 1,
RECEIVEDDATE: 1,
STATUS: 1,
avgduration: '$avgduration',
offduration: '$offduration'
}
})
dblights.aggregate({"$group" : {
... _id: {
... SWITCHID: "$_id.SWITCHID"
... },
... on_minus_off: { $sum:{ "$cond": [
... { "$eq": [ "$_id.STATUS", "on" ] },
... "$avgduration",
... { $subtract: [ 0, "$avgduration" ] }
... ]}}
... }}
... ])

Categories

Resources