#javascript #node.js #mongodb #mongoose
Вопрос:
Я написал запрос агрегации в мангусте,который всегда возвращает пустой массив, для перекрестной проверки запроса я написал тот же запрос в Pymongo, который подтвердил правильность моего запроса
ЭТО ИСХОДНЫЙ ЗАПРОС:
list(attendances.aggregate([{'$match':{'Date':{"$gte":start_date,"$lte":end_date},
'locationId':ObjectId("60dd6d303da6c17209d5ef68"),
'locationId':{'$exists':True},
'workerType':'Employee'
}},
{"$group":{'_id':{
'employeeId':'$employeeId',
'workerId':'$workerId',
'workerFullName':'$workerFullName'
},
'dailyPointsArray':{
'$push':{
'Date':'$Date',
'Points':'$shiftPoints'
}
},
'total_shift_points':{'$sum':'$shiftPoints'},
'total_duration':{'$sum':'$duration'},
}
}
]))
Что дает ожидаемый результат
[{'_id': {'employeeId': ObjectId('60e70b113fcb2eb7dfc67001'),
'workerId': '2005',
'workerFullName': 'JITENDRA OJHA'},
'dailyPointsArray': [{'Date': datetime.datetime(2021, 7, 8, 0, 0),
'Points': None},
{'Date': datetime.datetime(2021, 7, 9, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 10, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 11, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 12, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 13, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 14, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 15, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 16, 0, 0), 'Points': None}],
'total_shift_points': 0,
'total_duration': 0},
{'_id': {'employeeId': ObjectId('60e70b5c3fcb2eb7dfc73f05'),
'workerId': '1338',
'workerFullName': 'SHASHIKANT SINGH'},
'dailyPointsArray': [{'Date': datetime.datetime(2021, 7, 8, 0, 0),
'Points': None},
{'Date': datetime.datetime(2021, 7, 9, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 10, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 11, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 12, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 13, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 14, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 15, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 16, 0, 0), 'Points': None}],
'total_shift_points': 0,
'total_duration': 0},
{'_id': {'employeeId': ObjectId('60e70b2e3fcb2eb7dfc6c346'),
'workerId': '1676',
'workerFullName': 'AKASH BHINGARE'},
'dailyPointsArray': [{'Date': datetime.datetime(2021, 7, 8, 0, 0),
'Points': None},
{'Date': datetime.datetime(2021, 7, 9, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 10, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 11, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 12, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 13, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 14, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 15, 0, 0), 'Points': None},
{'Date': datetime.datetime(2021, 7, 16, 0, 0), 'Points': None}],
'total_shift_points': 0,
'total_duration': 0},
Но когда я перенес тот же запрос в express mongoose
router.get(
"/attendance-sheet/:fromDate/:toDate/:locationId/:workerType",
async (req, res) => {
console.log(
`API hit to /api/attendance/attendance-sheet/${req.params.fromDate}//${req.params.toDate}/${req.params.locationId}/${req.params.workerType}`
);
try {
const fromTime = formatTimeToIso(req.params.fromDate);
const toTime = formatTimeToIso(req.params.toDate);
console.log(fromTime,toTime,req.params.locationId,req.params.workerType);
const queryOutput = await Attendance.aggregate([{$match:{Date:{$gte:fromTime,$lte:toTime},
locationId:Mongoose.Types.ObjectId(req.params.locationId),
locationId:{$exists:true},
workerType:req.params.workerType
}},
{$group:{'_id':{
employeeId:'$employeeId',
workerId:'$workerId',
workerFullName:'$workerFullName'
},
dailyPointsArray:{
$push:{
Date:'$Date',
Points:'$shiftPoints'
}
},
total_shift_points:{$sum:'$shiftPoints'},
total_duration:{$sum:'$duration'},
}
}
])
return res.status(200).json({ attendanceSheet: queryOutput });
} catch (error) {
return res.status(500).json({ message: error.message });
}
}
);
Помощники
const formatTimeToIso = (dateString) => {
const d = new Date(dateString);
const n = new Date(d.getFullYear(), d.getMonth(), d.getDate());
const formattedTime = moment(n).format("YYYY-MM-DD[T00:00:00.000Z]");
return formattedTime
}
что дает пустой результат
Комментарии:
1. Можете ли вы подтвердить, что
req.params.locationId
этоObjectId
не аstring
?2. это строка,но разве мангуст не принимает объект в строке
3. MongoDB проверяет типы перед значениями, поэтому типы должны совпадать, попробуйте:
locationId: ObjectId(req.params.locationId)
4. @Saurabh не мангуст принимает objectid в строке => нет, вам нужно преобразовать его в тип ObjectId с помощью
mongoose.Types.ObjectId(req.params.locationId)
5. @turivishal Все еще не повезло , обновил мой код с помощью предложенного вами кода
Ответ №1:
Попробуйте заменить match
сцену на эту:
{
$match:{
'Date':{
$gte: new Date(req.params.fromDate),
$lte: new Date(req.params.toDate),
},
locationId:Mongoose.Types.ObjectId(req.params.locationId),
locationId:{$exists:true},
workerType:req.params.workerType,
}
},
Вместо форматирования его в строку ISO, просто создайте Date
объект с метками времени из параметров.