Why I am not getting any results from MongoDB, I want to fetch documents which is created less than 8 hours not more than that.
let fetchAllDetails = async (findExpression) => {
try {
let data = await userDetails.find(findExpression)
return data
}
catch (err) {
logger.error(`DB Fetch All Error ---> ${JSON.stringify(err)}`)
return false
}
}
exports.remindUsers = async () => {
let currentTime = Date.now()
console.log(new Date(getCurrentTime() - 30000), new Date(getCurrentTime()))
let fetchedUserData = await fetchAllDetails({ date_time: { $gt: new Date(currentTime - 6000) } }) // For one minute
console.log(fetchedUserData)
}
MongoDB Schema
const userDetails = new mongoose.Schema({
mobileNumber: {
type: String,
required: true,
unique: true,
},
date_time: {
type: Date,
required: true,
default: Date.now()
},
});
Related
I want to populate the busNumber from bus Bus table to the trip table.
Here's the bus model
const busSchema = new mongoose.Schema(
{
busNumber: {
type: String,
unique: true,
required: true,
},
seats: {
type: Number,
},
},
{
timestamps: true,
}
);
now I want to show the bus number inside the trip table instead of bus._id. I know how to exclude data but don't know how to include data from other collections.
here's the route model where I included the bus model
const routeSchema = new mongoose.Schema({
location:{
type: mongoose.Schema.Types.ObjectId,
ref: 'Location',
required: true
},
duration: {
type: Number,
required: true,
},
Bus:{
type: mongoose.Schema.Types.ObjectId,
ref:"Bus",
required: true
},
date: {
type:String,
required: true
},
},
{
timestamps: true,
});
here's the query:
router.get("/trips", async (req, res) => {
if ((!req.query.departure && !req.query.arrival) || !req.query.date) {
return res.send({
error: "Please enter the data to get the trip",
});
}
const { departure, arrival, date } = req.query;
const locations = await Location.find({
"departureLocation.name": departure,
"arrivalLocation.name": arrival,
});
const ids = locations.map(location => location._id);
const routes = await Route.find({
$and: [{ location: { $in: ids } }, { date }],
}).select(['-busId', '-location', '-_id', '-createdAt', '-updatedAt', '-__v']);
return !routes ? res.status(404).send() : res.status(200).send(routes);
});
Here's the result I am getting https://i.stack.imgur.com/AwK5N.png
How to use the populate() function to get data from another collection in mongoose
use this code for your populate Bus key
router.get("/trips", async (req, res) => {
if ((!req.query.departure && !req.query.arrival) || !req.query.date) {
return res.send({
error: "Please enter the data to get the trip",
});
}
const { departure, arrival, date } = req.query;
const locations = await Location.find({
"departureLocation.name": departure,
"arrivalLocation.name": arrival,
});
const ids = locations.map(location => location._id);
const routes = await Route.find({
$and: [{ location: { $in: ids } }, { date }],
}).populate("Bus").select(['-busId', '-location', '-_id', '-createdAt', '-updatedAt', '-__v']);
return !routes ? res.status(404).send() : res.status(200).send(routes);
});
I am building a bus ticket booking app in node.js. I have created 4 tables. 1 - users table, 2 - bus table, 3 - booking table, 4 - route table.
here's the trip model:
const routeSchema = new mongoose.Schema({
departureLocation: {
name: {
type: String,
required: true,
},
subLocation: { type: [String] },
time: {
type: String,
required: true
}
},
arrivalLocation: {
name: {
type: String,
required: true,
},
subLocation: { type: [String] },
time : {
type: String,
required: true
}
},
duration: {
type: Number,
required: true,
},
busId:{
type: mongoose.Schema.Types.ObjectId,
ref:"Bus",
required: true
},
date: {
type:String,
required: true
},
},
{
timestamps: true,
});
In that trip model only administrator(authenticated user) can add data about trip(like departure-Location, arrival-Location, bus-data and date)
router.post("/addTrip", auth, async (req, res) => {
const route = new Route(req.body);
try {
await route.save();
res.status(201).send(route);
} catch (e) {
res.status(500).send();
}
});
suppose there are search boxes for user to enter the details of the trip like this one
https://i.stack.imgur.com/oXvsj.png
User enters the data and that data converted into query string (like this: 127.0.0.1:3000/trips?departure=surat&arrival=bhavnagar&date=2022-05-30) and based on that query string I want to show the all matched trips to the user.
now I want to filter the data according to user's(non-authenticated users as well) need but I don't know how to do that.
router.get("/trips", async (req, res) => {
if(!req.query.departure || !req.query.arrival || !req.query.date){
return res.send({
error: "Please enter the data to get the trip"})
}
let departure = req.query.departure;
let arrival = req.query.arrival;
let date = req.query.date;
let routes = await Route.find().lean().exec();
let route = routes.find((route) => {
route.departureLocation.name.toLowerCase() == departure &&
route.arrivalLocation.name.toLowerCase() == arrival &&
route.date == date;
//What to write here
});
})
I have embedded the seat data in the bus model
const busSchema = new mongoose.Schema(
{
busNumber: {
type: String,
unique: true,
required: true,
},
seats: {
type: Number,
required: true
},
},
{
timestamps: true,
}
);
how to show the users the bus and seats available for that matched trips
You can filter the data using the find function:
router.get('/trips', async (req, res) => {
if (!req.query.departure || !req.query.arrival || !req.query.date) {
return res.send({
error: 'Please enter the data to get the trip',
});
}
let departure = req.query.departure;
let arrival = req.query.arrival;
let date = req.query.date;
let routes = await Route.find({
departureLocation: departure,
arrivalLocation: arrival,
date
}).lean().exec();
return res.status(200).json(routes);
});
Ok, so I have burnt hours on this and multiple various google searches, and I can't seem to solve this. So, I'm here for some help...
I am trying to use mongoose.findOneAndUpdate() to either add a document or update an existing document into a collection. I have done this many times before successfully, but I am stumped right now.
When the document is created in the mongodb it contains only this:
{
_id: <some mongo id>
faFlightID: 4839-fjgnkbk-adhoc
positions: [Array of Objects] <----These appear to be correct.
}
That's it. It is missing all of the other fields. I feel like I am missing something completely and totally obvious, but at this point I've been staring at it for so long, I probably can't see the forest for the trees
Here is my mongoose code:
const Flights = require('../models/faFlights.model');
const saveFlight = async (flight) => {
let position = {
timestamp: flight.timestamp,
longitude: flight.longitude,
latitude: flight.latitude,
groundspeed: flight.groundspeed,
altitude: flight.altitude,
heading: flight.heading,
altitudeStatus: flight.altitudeStatus,
altitudeChange: flight.altitudeChange,
};
const filter = { faFlightID: flight.faFlightID };
const update = { flight, $push: { positions: position } };
try {
let result = await Flights.findOneAndUpdate(filter, update {
upsert: true,
new: true,
});
console.log(result);
} catch (error) {
console.log(error);
}
};
And here is my faflights.model
const mongoose = require('mongoose');
const positionSchema = new mongoose.Schema({
timestamp: {
type: Date,
set: (d) => formatEpoch(d),
},
longitude: Number,
latitude: Number,
groundspeed: Number,
altitude: Number,
heading: Number,
altitudeStatus: String,
altitudeChange: String,
});
const faflightSchema = new mongoose.Schema(
{
TALON_ACT_ID: String,
faFlightID: String,
ident: {
type: String,
set: (acreg) => modifyACRegistration(acreg),
},
prefix: String,
type: String,
suffix: String,
origin: String,
destination: String,
timeout: Number,
departureTime: {
type: Date,
set: (d) => formatEpoch(d),
},
firstPositionTime: {
type: Date,
set: (d) => formatEpoch(d),
},
arrivalTime: {
type: Date,
set: (d) => formatEpoch(d),
},
positions: [positionSchema],
lowLongitude: Number,
lowLatitude: Number,
highLongitude: Number,
highLatitude: Number,
updateType: String,
waypoints: String,
},
{ collection: 'faflights' }
);
//Convert AC Registration formatting
const modifyACRegistration = (reg) => {
let firstCharacter = reg.substring(0, 1);
let remainingCharacter = reg.substring(1, 5);
return `${firstCharacter}-${remainingCharacter}`;
};
const formatEpoch = (epoch) => {
if (!epoch) return;
return new Date(epoch * 1000);
};
module.exports = mongoose.model('faflights', faflightSchema);
I am at a total loss.
Apparently, I just needed to leave my workstation for a while, or more coffee...or both. Needed to use $set to make it all better.
const filter = { faFlightID: flight.faFlightID };
const update = { $set: flight, $push: { positions: position } };
try {
let result = await Flights.findOneAndUpdate(filter, update {
upsert: true,
new: true,
});
console.log(result);
} catch (error) {
console.log(error);
}
Hi all so I am trying to make a post request that increments a value if it already exists and if not it should create a new item.
router.post('/', auth, async (req, res) => {
try {
const { name, price, image } = req.body;
var query = { name },
update = { $inc: { count: 1 } },
options = { upsert: true, new: true,};
await CartItem.findOneAndUpdate(query, update, options, function (
err,
data
) {
if (err) {
const newItem = new CartItem({
user: req.user.id,
name: name,
price: price,
image: image,
});
const item = newItem.save();
res.json(item);
} else {
res.json(data);
}
});
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CartItemSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'user',
},
name: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
count: {
type: Number,
},
image: {
type: String,
required: true,
},
});
module.exports = CartItem = mongoose.model('cartItem', CartItemSchema);
So there are two problems here that I cannot wrap my head around(Pretty new with MongoDb, did do my research).
I can get the count to increment, but it increments with 2 or even more instead of 1. (I know other users also experienced this)
If the item is already in the cart(name matches) I want a new item to be added which does happen, but it only adds the name, count and Id. I want it to add the user, name, price and image.
Would appreciate some assistance.
you should create your document with a default value equals to 0.
define count at your schema like the following:
count: {
type: Number,
default: 0
}
then use { $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }.
link to docs: https://docs.mongodb.com/manual/reference/operator/update/inc/
I'm working on a project where in one model I need to set the value of a field based on another fields value. Let me explain with some code.
Destination model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const DestinationSchema = new Schema({
name: {
type: String,
required: true
},
priority: {
type: Number,
default: 0,
max: 10,
required: true
}
})
DestinationSchema.statics.getPriority = function(value) {
return this.findOne({ _id: value })
}
const Destination = mongoose.model('Destination', DestinationSchema)
exports.Destination = Destination
Task model
const mongoose = require('mongoose')
const { Destination } = require('../_models/destination.model')
const Schema = mongoose.Schema;
const TaskSchema = new Schema({
priority: {
type: Number,
required: true,
min: 0,
max: 25
},
from: {
type: Schema.Types.ObjectId,
ref: 'Destination',
required: true
},
to: {
type: Schema.Types.ObjectId,
ref: 'Destination',
required: true
},
type: {
type: Number,
required: true,
min: 0,
max: 3
}
}, {
timestamps: true
})
TaskSchema.pre('save', async function () {
this.priority = await Destination.getPriority(this.from).then(doc => {
return doc.priority
})
this.priority += await Destination.getPriority(this.to).then(doc => {
return doc.priority
})
this.priority += this.type
})
Task Controller update function
exports.update = async function (req, res) {
try {
await Task.findOneAndUpdate({
_id: req.task._id
}, { $set: req.body }, {
new: true,
context: 'query'
})
.then(task =>
sendSuccess(res, 201, 'Task updated.')({
task
}),
throwError(500, 'sequelize error')
)
} catch (e) {
sendError(res)(e)
}
}
When I create a new Task, the priority gets set in the pre save hook just fine as expected. But I'm hitting a wall when I need to change Task.from or Task.to to another destination, then I need to recalculate the tasks priority again. I could do it on the client side, but this would lead to a concern where one could just simply send a priority in an update query to the server.
My question here is, how can I calculate the priority of a Task when it gets updated with new values for from and to? Do I have to query for the document which is about to get updated to get a reference to it or is there another cleaner way to do it, since this would lead to one additional hit to the database, and I'm trying to avoid it as much as possible.
In your task schema.
you have to use pre("findOneAndUpdate") mongoose middleware. It allows you to modify the update query before it is executed
Try This code:
TaskSchema.pre('findOneAndUpdate', async function(next) {
if(this._update.from || this._update.to) {
if(this._update.from) {
this._update.priority = await Destination.getPriority(this._update.from).then(doc => {
return doc.priority
});
}
if(this._update.to) {
this._update.priority += await Destination.getPriority(this._update.to).then(doc => {
return doc.priority
});
}
}
next();
});