I'm trying to create a reservation with node.js and express and mongoose!
This is my Schema:
let mongoose = require("mongoose");
let Schema = mongoose.Schema;
let reservationSchema = new Schema({
car: [
{
type: Schema.Types.ObjectId,
ref: "cars",
required: true,
unique: false,
},
],
client: [
{
type: Schema.Types.ObjectId,
ref: "users",
required: true,
unique: false,
},
],
request: {
type: "Date",
default: Date.now(),
},
from: {
type: "Date",
required: true,
},
days: {
type: "Number",
required: true,
},
});
let reservation = mongoose.model("Reservation", reservationSchema);
module.exports = reservation;
And this is my function that I'm using to make it work while the dates does not match
function check(reservations, newReservation) {
console.log("chegou");
return new Promise(function (resolve, reject) {
ReservationModel.find({}, function (err, reservations) {
console.log("chegou aqui lol");
console.log([reservations]);
console.log(newReservation);
if (err) reject(err);
reservations.forEach(myFunction);
function myFunction(reservations) {
console.log("Siga ze");
console.log(reservations.car);
console.log(newReservation.car);
if ((reservations.car = newReservation.car)) {
console.log("chegou ao if");
let date = reservations.from;
let days = reservations.days;
var result = new Date(date);
result.setDate(result.getDate() + days);
console.log(result);
console.log(newReservation.from);
if (newReservation.from >= result) {
console.log("devia funfar crlh");
resolve(newReservation);
} else {
console.log("Nao funfou");
}
} else {
console.log("fds nao da esta merda pqp");
}
}
});
});
}
It reaches the
if (newReservation.from >= result) {
console.log("devia funfar crlh");
resolve(newReservation);
So it should work, but when I get to the part when it is going to save to the database it gives me the error:
E11000 duplicate key error collection: rent-a-car.reservations index: car_1 dup key: { car: ObjectId('625af24b81b1edc90fdef50a') }
Saying that the car is already in use, and I have specifically in the Schema to not be unique.
What can I do?
Related
I have a mongoose model where one of the fields is an array of dates and I need to query the collection to find any document that has a date between the 7 past days inside that array, but when I try to use $gt or $gte it doesn't return me the documents, even if exists (I have checked if the documents exist).
Here it is an example of the object
It shouldn't return me objects with more than 7 days past.
Here is the code that I'm using:
const { subDays } = require("date-fns");
const mongoose = require("mongoose");
const Journey = require("./models/Journey");
const url = "my-db-url";
mongoose.set("useNewUrlParser", true);
mongoose.set("useUnifiedTopology", true);
mongoose.set("useCreateIndex", true);
mongoose.set("useFindAndModify", false);
mongoose.connect(url, (err) => {
if (err) throw err;
console.log("Mongoose connected");
});
Journey.find({
hospital: "5e6fc0d98db5810012aeb8fe",
active: false,
timestampStart: {
$gte: subDays(new Date(), 7)
}
})
.lean()
.exec((err, journeys) => {
if (err) throw err;
console.log(journeys[0]);
});
The Journey model:
const { Schema, model } = require("mongoose");
const JourneySchema = new Schema(
{
tag: {
type: Schema.Types.ObjectId,
required: true,
ref: "Tag",
},
patient: {
type: Schema.Types.ObjectId,
required: true,
ref: "Patient",
},
hospital: {
type: Schema.Types.ObjectId,
required: true,
ref: "Hospital",
},
department: {
type: [String],
required: true,
},
timestampStart: {
type: [Date],
required: true,
},
timestampEnd: {
type: [Date],
required: true,
},
active: {
type: Boolean,
default: true,
},
rssi: {
type: [String],
required: true,
},
},
{
timestamps: true,
}
);
module.exports = model("Journey", JourneySchema);
Can anyone help me build this filter?
The date query seems to working just fine. I think the problem would be with the hospital, and active key. In the sample object that you have provided, both are missing. Can you check it by removing those keys in the query, or by adding them in the collection.
I am having an issue with mongoose and nodejs. May be i am writing wrong code or any other problem please help. Here is my controller file. alldata.save gives [ParallelSaveError]
let createData = async function(req,res,next) {
let body = req.body;
let alldata = new League(body);
let start_time = new Date().getTime();
try {
await Leaguecategories.find({})
.then(async function(categories) {
categories.forEach(async function(category) {
//here i am assigning foreign key
alldata.league_category_id = category._id;
await alldata.save(function(err, book){
if(err){
console.log(err);
}else{
res.send({status: 0, statusCode:"success", message: "Successfully inserted."})
}
});
})
})
}
catch (error){
return res.send({status : 1 , statusCode : "error" , message : error.message})
}
}
Here is my Leaguecategories model
var mongoose = require('mongoose');
const league_categories = new mongoose.Schema({
name: {
type: String,
required: true
},
active: {
type: String,
required: true
},
create_date: {
type: Date,
required: true,
default: Date.now
},
league_type_id: {
type: String,
required: 'league_type',
required:true
}
})
module.exports = mongoose.model('Leaguecategories', league_categories)
Here is my League model
var mongoose = require('mongoose');
const league = new mongoose.Schema({
title: {
type: String,
required: true
},
pool_price: {
type: Number,
required: true
},
entry_fee: {
type: Number,
required: true
},
total_spots: {
type: Number,
required: true
},
start_time: {
type: Date,
required: true
},
end_time: {
type: Date,
required: true
},
create_date: {
type: Date,
required: true,
default: Date.now
},
active: {
type: String,
required: true
},
league_category_id: {
type: String,
ref: 'Leaguecategories',
required:true
}
})
module.exports = mongoose.model('League', league)
You have to create new instance of League each time. Like this:
categories.forEach(async function(category) {
//here i am assigning foreign key
let alldata = new League(body);
alldata.league_category_id = category._id;
...
});
Suggestion:
Why are you using both async/await and .then()? You should use only one of them. Also, there are some other problems.
await won't work inside forEach
You are calling res.send() every time you call .save(). This might end up throwing an error as well.
You can refactor the code like this.
try {
const categories = await Leaguecategories.find({});
const promises = categories.map(function (category) {
//here i am assigning foreign key
let alldata = new League(body);
alldata.league_category_id = category._id;
return alldata.save();
});
await Promise.all(promises);
res.send({ status: 0, statusCode: "success", message: "Successfully inserted." })
} catch (error) {
return res.send({ status: 1, statusCode: "error", message: error.message });
}
I have set of products indexed in elasticsearch. I`m searching for "title" on my schema.
When I search "fre" or "fresh" I see a result.
But when I search for "small fresh" I don't see any result.
Is it possible to use wildcard with spaces ?
I added es_indexed: "not_analyzed" but no luck.
This is my Product Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var mongoosastic = require("mongoosastic");
const deepPopulate = require("mongoose-deep-populate")(mongoose);
var Owner = require("./user");
var Category = require("./category");
var Reviews = require("./review");
const ProductSchema = new Schema(
{
category: {
type: Schema.Types.ObjectId,
ref: "Category",
es_indexed: true,
es_type: "nested",
es_include_in_parent: true
},
owner: {
type: Schema.Types.ObjectId,
ref: "User",
es_indexed: true,
es_type: "nested",
es_include_in_parent: true
},
reviews: [
{
type: Schema.Types.ObjectId,
ref: "Review",
es_indexed: true,
es_type: "nested",
es_include_in_parent: true
}
],
image: { type: String, es_indexed: true },
title: {
type: String,
es_indexed: "not_analyzed"
},
description: { type: String, es_indexed: true },
price: { type: Number, es_indexed: true },
crated: { type: Date, default: Date.now, es_indexed: true }
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
}
);
ProductSchema.virtual("averageRating").get(function() {
var rating = 0;
if (this.reviews.length == 0) {
rating = 0;
} else {
this.reviews.map(review => {
rating += review.rating;
});
rating = rating / this.reviews.length;
}
return rating;
});
ProductSchema.plugin(deepPopulate);
ProductSchema.plugin(mongoosastic, {
populate: [{ path: "category" }, { path: "owner" }, { path: "reviews" }]
});
let Model = mongoose.model("Product", ProductSchema);
Model.createMapping(function(err, mapping) {
if (err) {
console.log("error creating mapping (you can safely ignore this)");
console.log(err);
} else {
console.log("mapping created!");
console.log(mapping);
}
});
var stream = Model.synchronize();
var count = 0;
stream.on("data", (err, doc) => {
console.log(doc);
count++;
});
stream.on("close", () => console.log("indexed " + count + " documents!"));
stream.on("error", err => console.log(err));
Model.SyncToAlgolia();
Model.SetAlgoliaSettings({
searchableAttributes: ["title"]
});
module.exports = Model;
This is my Search function
async function search(frompage) {
let fullString = "*" + "small fresh" + "*";
let startsFrom = frompage * 10;
console.log(fullString);
const response = await esClient.search({
index: "products",
type: "product",
from: startsFrom,
body: {
query: {
wildcard: {
title: fullString
}
}
}
});
return response;
}
I'm trying to update the value of an element inside an array of my document.
The common way of update via save works as expected, but trying to use an static method, like findByIdAndUpdate doesn't work as expected.
Here bellow I paste the code I'm currently using:
var UserSchema = new mongoose.Schema({
nickname: { type: String, trim: true},
username: { type: String, trim: true },
notifications: [{
a: {
_id: { type: mongoose.Schema.Types.ObjectId, ref: 'x' },
x: { type: mongoose.Schema.Types.ObjectId, ref: 'y' }
},
b: {
_id: { type: mongoose.Schema.Types.ObjectId, ref: 'y' },
x: { type: mongoose.Schema.Types.ObjectId, ref: 'y' }
},
read: { type: Number, default: 0 }, // 0 - Unread, 1 - read
ts: { type: Date, default: Date.now }
}]
}, { timestamps: { createdAt: 'created_at' } });
// This works as expected
UserSchema.statics.rNSave = function (user_id, notification_id) {
var vm = this;
return new Promise(function (resolve, reject) {
vm.findById(user_id, function (err, data) {
if (err) {
reject(new Error(err));
} else {
var notifications = data.notifications, i = 0;
for (i; i < notifications.length; i += 1) {
if (data.notifications[i]._id.toString() === notification_id) {
data.notifications[i].read = 1;
data.save({ validateBeforeSave: false }, function (err, updatedData) {
if (err) {
reject(new Error(err));
} else {
resolve();
}
});
return;
}
}
return reject('Error');
}
});
});
};
// This one is not working
UserSchema.statics.rNStatic = function (user_id, notification_id) {
return this.findByIdAndUpdate({ _id: user_id, notifications: { $elemMatch: { _id: notification_id }}}, { $set: { 'notifications.$.read': 1 }}).exec();
};
Any help with this?
Thanks in advice.
I have 2 collections: bookings and timeslots.
models/booking.js:
var mongoose = require ('../config/db');
var Schema = require('mongoose').Schema;
var ObjectId = Schema.ObjectId;
var bookingSchema = new Schema({
start: {
type: Number,
required: true
},
end: {
type: Number,
required: true
},
date: {
type: Date,
required: true,
default: Date.now
}
});
models/time_slot.js:
var mongoose = require ('../config/db');
var Schema = require('mongoose').Schema;
var ObjectId = Schema.ObjectId;
var timeSlotSchema = new Schema({
start: {
type: Number,
required: true
},
end: {
type: Number,
required: true
},
date: {
type: Number,
required: true,
default: Time.Today
},
enabled: {
type: Boolean,
required: true,
default: true,
},
pickup: {
type: Boolean,
required: true,
default: true,
}
});
Both have a field start in common. I would like to be able to get the entries from the collection timeslots in which the value of start has occurred in bookings.
I have tried:
controllers/time_slot.js:
var timeSlotModel = require('../models/time_slot').model;
var Booking = require('./booking');
Booking.getBookings({}, function(err, bookings) {
if (err) {
console.error(err);
} else {
timeSlotModel.find({start: bookings.start}, function(err, slots) {
if (err) {
console.error(err);
} else {
return next(null, slots);
}
}
}
But that doesn't work, unsurprisingly, and I get the error:
MongooseError: Cast to number failed for value "undefined" at path "start"
You can do it like this:
Booking.getBookings({}, function(err, bookings) {
if (err) {
console.error(err);
} else {
// build array with unique "start" values from bookings
var starts = bookings
.map(booking => booking.start)
.filter((val, i, self) => self.indexOf(val) === i)
// find by these start values
var query = {start: {$in: starts}}
timeSlotModel.find(query, function(err, slots) {
if (err) {
console.error(err);
} else {
return next(null, slots);
}
}
}