объединенный запрос не работает в Мангусте в nodejs

#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 объект с метками времени из параметров.