Estoy tratando de hacer una API que haga uso de 2 bases de datos para generar una multa. Aquí está el código:
router.get("/generateFine/:bookingID/:currDate", function (req, res, next) { var currDate, returnDate, fine, totalFine = 0; Booking.findOne({ _id: req.params.bookingID }).then(function (booking) { Car.findOne({ _id: booking.carID }).then(function (car) { currDate = Date.parse(req.params.currDate) / 1000 / 3600 / 24; returnDate = Date.parse(booking.bookingDates[1]) / 1000 / 3600 / 24; fine = car.fine; if (currDate > returnDate) { totalFine = fine * (currDate - returnDate); } console.log(totalFine); // res.send(totalFine); }); console.log("totalFine is " + totalFine); // res.send(totalFine); }); });Estos son los dos esquemas utilizados en el código: Esquema de reserva:
{ "_id" : ObjectId("621bf46602edf12942f0d5c9"), "carID" : "621b87af70c150da70b1dabf", "bookingDates" : [ "2022-03-05", "2022-03-06" ], }Esquema del coche:
{ "_id" : ObjectId("621b87af70c150da70b1dabf"), "name" : "Toyota", "rate" : 60, "fine" : 10, "datesBooked" : [ { "from" : "2022-03-05", "to" : "2022-03-06" }, { "from" : "2022-03-07", "to" : "2022-03-08" }, { "from" : "2022-03-09", "to" : "2022-03-10" } ], "__v" : 0 }Quiero devolver la multa generada al usuario. Cuando intento enviar el resultado, arroja un error. El primer registro de la consola imprime el resultado correcto, pero el segundo registro de la consola imprime 0. Además, ¿cómo puedo enviar el resultado sin obtener un error? ¡Gracias ya!
Puede usar la etapa de canalización de agregación $lookup para incluir el documento del automóvil que coincide con el campo carID , crear campos calculados adicionales que lo ayudarán a obtener la multa total mientras usa los operadores de agregación necesarios.
Esencialmente, necesitaría ejecutar una canalización agregada que sigue:
const mongoose = require('mongoose'); router.get('/generateFine/:bookingID/:currDate', async function (req, res, next) { const currDate = new Date(req.params.currDate); const [{ totalFine }] = await Booking.aggregate([ { $match: { _id: mongoose.Types.ObjectId(req.params.bookingID) }}, { $lookup: { from: 'cars', // or from: Car.collection.name let: { carId: { $toObjectId: '$carID' } }, // convert the carID string field to ObjectId for the match to work correctly pipeline: [ { $match: { $expr: { $eq: [ '$_id', '$$carId' ] } } } ], as: 'car' } }, { $addFields: { car: { $arrayElemAt: ['$car', 0 ] }, // get the car document from the array returned above returnDate: { $toDate: { $arrayElemAt: ['$bookingDates', 1 ]} } } }, // compute the overdue days { $addFields: { overdueDays: { $trunc: { $ceil: { $abs: { $sum: { $divide: [ { $subtract: [currDate, '$returnDate'] }, 60 * 1000 * 60 * 24 ] } } } } } } }, { $project: { // project a new field totalFine: { $cond: [ { $gt: [currDate, '$returnDate'] }, // IF current date is greater than return date { $multiply: ['$car.fine', '$overdueDays'] }, // THEN multiply car fine with the overdue days 0 // ELSE total fine is 0 ] } } } ]).exec(); console.log("totalFine is " + totalFine); // res.send(totalFine); });