Mongobooster aggregate function running error - javascript

when i am trying to run the query using aggregate function in mongobooster on windows 7 32 bit pc...its giving me this error..please help me to resolve this error...
"message" : "not authorized on strict to execute command { aggregate: 'PermanentBookings', pipeline: [ { $match: { $or: [ { city: 'Torino' } ], init_date: { $gte: new Date(1506816000000), $lte: new Date(1509494399000) } } }, { $project: { _id: 0.0, moved: { $ne: [ { $arrayElemAt: [ '$origin_destination.coordinates', 0.0 ] }, { $arrayElemAt: [ '$origin_destination.coordinates', 1.0 ] } ] }, duration: { $devide: [ { $subtract: [ '$final_time', '$init_time' ] }, 60.0 ] }, hourDay: { $hour: '$init_date' }, day: { $dayOfMonth: '$init_date' } } }, { $match: { moved: true, duration: { $lte: 180.0, $gt: 2.0 } } }, { $sort: { day: 1.0, hourDay: 1.0 } }, { $skip: 0.0 } ], cursor: {} }",
"stack" : "MongoError: not authorized on strict to execute command { aggregate: 'PermanentBookings', pipeline: [ { $match: { $or: [ { city: 'Torino' } ], init_date: { $gte: new Date(1506816000000), $lte: new Date(1509494399000) } } }, { $project: { _id: 0.0, moved: { $ne: [ { $arrayElemAt: [ '$origin_destination.coordinates', 0.0 ] }, { $arrayElemAt: [ '$origin_destination.coordinates', 1.0 ] } ] }, duration: { $devide: [ { $subtract: [ '$final_time', '$init_time' ] }, 60.0 ] }, hourDay: { $hour: '$init_date' }, day: { $dayOfMonth: '$init_date' } } }, { $match: { moved: true, duration: { $lte: 180.0, $gt: 2.0 } } }, { $sort: { day: 1.0, hourDay: 1.0 } }, { $skip: 0.0 } ], cursor: {} }" +
"at Function.MongoError.create (C:\\Users\\Pinky\\AppData\\Local\\mongobooster\\app-3.5.7\\resources\\app.asar\\node_modules\\mongodb-core\\lib\\error.js:31:11)" +
"at queryCallback (C:\\Users\\Pinky\\AppData\\Local\\mongobooster\\app-3.5.7\\resources\\app.asar\\node_modules\\mongodb-core\\lib\\cursor.js:212:36)" +
"at C:\\Users\\Pinky\\AppData\\Local\\mongobooster\\app-3.5.7\\resources\\app.asar\\node_modules\\mongodb-core\\lib\\connection\\pool.js:469:18" +
"at _combinedTickCallback (internal/process/next_tick.js:67:7)" +
"at process._tickCallback (internal/process/next_tick.js:98:9)",
"name" : "MongoError",
"ok" : 0,
"errmsg" : "not authorized on strict to execute command { aggregate: 'PermanentBookings', pipeline: [ { $match: { $or: [ { city: 'Torino' } ], init_date: { $gte: new Date(1506816000000), $lte: new Date(1509494399000) } } }, { $project: { _id: 0.0, moved: { $ne: [ { $arrayElemAt: [ '$origin_destination.coordinates', 0.0 ] }, { $arrayElemAt: [ '$origin_destination.coordinates', 1.0 ] } ] }, duration: { $devide: [ { $subtract: [ '$final_time', '$init_time' ] }, 60.0 ] }, hourDay: { $hour: '$init_date' }, day: { $dayOfMonth: '$init_date' } } }, { $match: { moved: true, duration: { $lte: 180.0, $gt: 2.0 } } }, { $sort: { day: 1.0, hourDay: 1.0 } }, { $skip: 0.0 } ], cursor: {} }",
"code" : 13,
"codeName" : "Unauthorized"
}

Related

MongoDB aggregate add new field with multiple conditions

I cannot figure to add a new field with multiple conditions in MongoDB. Here is how DB looks like,
const db = [
{
_id: 1,
isActived: false, // Drafted
isScheduled: false,
isExpired: false
},
{
_id: 2,
isActived: true,
isScheduled: true, // Scheduled
isExpired: false
},
{
_id: 3,
isActived: true, // Expired
isScheduled: false,
isExpired: true
},
{
_id: 4,
isActived: true, // Actived
isScheduled: false,
isExpired: false
},
]
Conditions are:
if (!isActived) status = "Draft"
if (isActived && isScheduled) status = "Scheduled"
if (isActived && isExpired) status = "Expired"
if (isActived && !isScheduled && !isExpired) status = "Actived"
I can figure out only one condition and cannot solve it any further. Here is what I did so far
{
$addFields: {
status: {
$cond: [
{
$and: [
{ $eq: ["$isActived", true] },
{ $eq: ["$isScheduled", true] },
],
},
"Actived",
"Scheduled",
],
$cond: [
{
$and: [
{ $eq: ["$isActived", true] },
{ $eq: ["$isExpired", true] },
],
},
"Actived",
"Expired",
],
},
},
}
The result is not what I expected.
Any suggestion. Thank You.
You can concatenate if/else in this way:
Pseudocode:
if !isActived:
return "Draft"
else
if !isScheduled && !isExpired:
return "Actived"
else
if isScheduled:
return "Scheduled"
else
return "Expired" //<-- Since one of "isScheduled" and "isExpired" should be true
Take care on last line where may you can have isScheduled and isExpired to true, so you logic can change.
db.collection.aggregate([
{
"$set": {
"status": {
"$cond": {
"if": {
"$eq": [
"$isActived",
false
]
},
"then": "Draft",
"else": {
"$cond": {
"if": {
"$and": [
{
"$eq": [
"$isExpired",
false
]
},
{
"$eq": [
"$isScheduled",
false
]
}
]
},
"then": "Actived",
"else": {
"$cond": {
"if": {
"$eq": [
"$isScheduled",
true
]
},
"then": "Scheduled",
"else": "Expired"
}
}
}
}
}
}
}
}
])
Example here
Simple nested conditions, working solution
db.collection.aggregate([
{
$addFields: {
status: {
$cond: [
{
$and: [
{ $eq: [ "$isActived", true ] },
{ $eq: [ "$isScheduled", false ] },
{ $eq: [ "$isExpired", false ] },
],
},
"Actived",
{
$cond: [
{
$and: [
{ $eq: [ "$isActived", true ] },
{ $eq: [ "$isExpired", true ] },
],
},
"Expired",
{
$cond: [
{
$and: [
{ $eq: [ "$isActived", true ] },
{ $eq: [ "$isScheduled", true ] },
],
},
"Scheduled",
{
$cond: [
{
$and: [
{ $eq: [ "$isActived", false ] },
],
},
"Draft",
null,
],
},
],
},
],
},
],
},
},
},
])

MongoDB $addFields, add boolean field based on condition

I have a list of places documents which have opening times, which is an object detailed below:
"openingTimes": {
"Wednesday": [ // array of shifts
{
"startTime": { "hour": 1, "minute": 0 }, // shift starts
"endTime": { "hour": 10, "minute": 0} //shift ends
},
{
"startTime": { "hour": 15, "minute": 0 },
"endTime": { "hour": 23, "minute": 59 }
}
],
"Thursday": [
{
"startTime": { "hour": 0, "minute": 0 },
"endTime": { "hour": 23, "minute": 59 }
}
],
}
I need to add a field to indicate if the place is open now or not,
{
$addFields: {
isOpenNow: {
$and: [
{
$or: [
{
$lt: ['$openingTimes.Wednesday.startTime.hour', 14]
},
{
$and: [
{
$lte: ['$openingTimes.Wednesday.startTime.hour', 14]
},
{
$lte: ['$openingTimes.Wednesday.startTime.minute', 0]
}
]
}
]
},
{
$or: [
{
$gt: ['$openingTimes.Wednesday.endTime.hour', 14]
},
{
$and: [
{
$gte: ['$openingTimes.Wednesday.endTime.hour', 14]
},
{
$gte: ['$openingTimes.Wednesday.endTime.minute', 0]
}
]
}
]
}
]
}
but it ends up with a result of false I think $gte: ['$openingTimes.Wednesday.endTime.hour', 14] compares the array of hours to 14, is there is a way to indicate if the place is open based on it's shifts.
You can try below aggregate:
{
isPlaceOPen: {
$cond: {
if: { $gt: [{ $size: {
$filter: {
input: '$openingTimes.Wednesday',
as: 'shift',
cond: {
$and: [
{
$or: [
{
$lt: [
'$$shift.startTime.hour',
14
]
},
{
$and: [
{
$lte: [
'$$shift.startTime.hour',
14
]
},
{
$lte: [
'$$shift.startTime.minute',
0
]
}
]
}
]
},
{
$or: [
{
$gt: [
'$$shift.endTime.hour',
14
]
},
{
$and: [
{
$gte: [
'$$shift.endTime.hour',
14
]
},
{
$gte: [
'$$shift.endTime.minute',
0
]
}
]
}
]
}
]
}
}
} }, 0] },
then: true,
else: false,
},
}
}

Mongodb Aggregate - Grouping by hour for today

I was wondering if someone could help me get my aggregation function right. I'm trying to count load of visits of my Fitness. I have Visits table where every visit (from, to) dates are saved. Also sub-visits to some services saved too.
[{
"from": ISODate("2020-01-17T10:23:27.645Z"),
"to": ISODate("2020-01-17T12:23:28.760Z"),
"visits": [
{
"from": ISODate("2020-01-17T10:23:27.646Z"),
"to": ISODate("2020-01-17T10:30:28.760Z"),
"service": ObjectId("5e05f17d6b7f7920d4a62403")
},
{
"from": ISODate("2020-01-17T10:30:29.760Z"),
"to": ISODate("2020-01-17T12:23:28.760Z"),
"service": ObjectId("5d05f17dt57f7920d4a62404")
}
],
...
},
{
"from": ISODate("2020-01-17T10:40:00.000Z"),
"to": ISODate("2020-01-17T11:30:28.760Z"),
"visits": [
{
"from": ISODate("2020-01-17T10:40:00.000Z"),
"to": ISODate("2020-01-17T11:30:28.760Z"),
"service": ObjectId("h505f17s6b2f7920d4a6295y")
}
],
...
}
]
I wanted to reach the result for today from 00:00 if current time is 13:35 then get until 13:00 like :
[{
'date': '2020-01-18T00:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T00:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T00:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T01:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T02:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T03:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T04:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T05:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T06:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T07:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T08:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T09:00:0.000Z'
'visits': 0
},
{
'date': '2020-01-18T010:00:0.000Z'
'visits': 2
},
{
'date': '2020-01-18T11:00:0.000Z'
'visits': 2
},
{
'date': '2020-01-18T12:00:0.000Z'
'visits': 1
},
{
'date': '2020-01-18T13:00:0.000Z'
'visits': 0
}]
Tried too many examples, but nothing worked, Please help !
EXPLANATION
If we use $$NOW, we get current date. If you setup currDate, today, nextDay manually, MongoDB aggregation will limit desired values.
Now, we calculate how many hours from today (yyyy-MM-dd 00:00:00) - currDate (yyyy-MM-dd 13:35:00) ~ 13 hours and with $range operator create array
We flatten interval and apply filtering
You may use such query:
db.collection.aggregate([
{
$addFields: {
nextDay: {
$add: [
{
$dateFromString: {
dateString: {
$substr: [
{
$toString: "$$NOW"
},
0,
10
]
},
format: "%Y-%m-%d"
}
},
{
$multiply: [
24,
60,
60,
1000
]
}
]
},
today: {
$dateFromString: {
dateString: {
$substr: [
{
$toString: "$$NOW"
},
0,
10
]
},
format: "%Y-%m-%d"
}
},
currDate: {
$dateFromString: {
dateString: {
$substr: [
{
$toString: "$$NOW"
},
0,
13
]
},
format: "%Y-%m-%dT%H",
timezone: "-01"
}
}
}
},
{
$addFields: {
interval: {
$range: [
0,
{
$add: [
{
$divide: [
{
$subtract: [
"$currDate",
"$today"
]
},
{
$multiply: [
60,
60,
1000
]
}
]
},
1
]
},
1
]
}
}
},
{
$unwind: "$interval"
},
{
$addFields: {
date: {
$add: [
"$today",
{
$multiply: [
"$interval",
60,
60,
1000
]
}
]
},
nextHour: {
$add: [
"$today",
{
$multiply: [
{
$add: [
"$interval",
1
]
},
60,
60,
1000
]
}
]
}
}
},
{
$project: {
_id: 0,
date: 1,
today: 1,
nextDay: 1,
visits: {
$reduce: {
input: "$visits",
initialValue: 0,
in: {
$add: [
"$$value",
{
$cond: [
{
$or: [
{
$and: [
{
$gte: [
"$$this.from",
"$date"
]
},
{
$lte: [
"$$this.from",
"$nextHour"
]
}
]
},
{
$and: [
{
$lte: [
"$date",
"$$this.to"
]
},
{
$gte: [
"$date",
"$$this.from"
]
}
]
}
]
},
1,
0
]
}
]
}
}
}
}
},
{
$match: {
$expr: {
$and: [
{
$gte: [
"$date",
"$today"
]
},
{
$lte: [
"$date",
"$nextDay"
]
},
]
}
}
},
{
$group: {
_id: "$date",
visits: {
$sum: "$visits"
}
}
},
{
$sort: {
_id: 1
}
}
])
MongoPlayground
For JS setup, click here
You may try this solution if you want more elegant way

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