Find matched data from object in mongoose - node.js

I want to get all matched data from an object but I am getting an empty array.
Here is the location table:
const locationSchema = new mongoose.Schema(
{
location: {
name: {
type: String,
unique: true,
required: true,
lowercase: true,
},
subLocation: [String],
},
},
{
timestamps: true,
}
);
and it is embedded in route table:
const routeSchema = new mongoose.Schema(
{
location: {
from: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
to: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
},
busId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Bus",
required: true,
},
date: {
type: String,
required: true,
},
departureTime: {
type: Number,
required: true,
},
arrivalTime: {
type: Number,
required: true,
},
},
{
timestamps: true,
}
);
Now I am running query to get the matched data from route table but I am getting an empty array.
http://127.0.0.1:3000/trips?from=6295871d69217e9c28cf7f19&to=6295874869217e9c28cf7f1c&date=2022-06-02
here is the query :
router.get("/trips", async (req, res) => {
if (!req.query.from || !req.query.to || !req.query.date) {
return res.send({
error: "Please enter the data to get the trip",
});
}
const { from, to, date } = req.query;
const routes = await Route.find({
from,
to,
date,
});
Another Question:
I am passing an Id as a value now I want to pass value as a sting like this: from=Mumbai&to=Ahmedabad&date=2022-06-02.
How to do that? because whenever I do that I am getting a casting error

I suggest you to change the location schema to have from and to locations separately like below.
const locationSchema = new mongoose.Schema(
{
fromLocation: {
name: {
type: String,
unique: true,
required: true,
lowercase: true,
},
subLocation: [String],
},
toLocation: {
name: {
type: String,
unique: true,
required: true,
lowercase: true,
},
subLocation: [String],
},
},
{
timestamps: true,
}
);
Thus the route schema should look like this
const routeSchema = new mongoose.Schema(
{
location: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
date: {
type:String,
required: true
},
....
....
And then do something like this...
let locations = await Location.find({
'fromLocation.name': from,
'toLocation.name': to,
});
After that
const ids = locations.map(location => location._id)
const routes = await Route.find({$and: [{location : {$in: ids}},{date}]});
const route = routes.find(()=>{
return ([{ date }, { routes }])
});

Related

How to get a certain field of an embedded MongoDB document knowing its ObjectId

I have two collections in MongoDB database, Post and User. Each post contains the creator's ObjectId. When fetching all posts from the database, I want to add the name information, which is a field of User/creator. I tried to access the name field by post.creator.name, but it is not working.
const postSchema = new Schema(
{
title: {
type: String,
required: true,
},
category: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
imageUrl: {
type: String,
required: true,
},
creator: {
type: Schema.Types.ObjectId,
ref: "User",
required: true,
},
},
{ timestamps: true }
);
const userSchema = new Schema({
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
isExpert: {
type: Boolean,
required: true,
},
posts: [
{
type: Schema.Types.ObjectId,
ref: "Post",
},
],
});
exports.getPosts = (req, res, next) => {
Post.find({}).then((posts) => {
const postsWithAuthorName = posts.map(post => {
return {
...post,
name: post.creator.name
}
})
res.status(200).json({
posts: postsWithAuthorName,
});
});
};
Try this
Post.find({}).populate('creator', 'name')
See populate doc for reference.
When you query posts, creator is just an ObjectId, so you can't just call .name on it. To make it work you need to lookup this data by using e.g. populate.

remove referencing objects on deletion from array in MongoDB

I have 2 schemas User and Restaurant, and user has an array of restaurants, am trying to reach when deleting the restaurant delete its reference from user automatically, am trying to reach it with the model.pre('remove')..but when I delete a restaurant the reference id it still exist in User.
Here is my User Schema:
const userSchema = new Schema(
{
email: {
type: String,
trim: true,
// required: true,
unique: true,
},
password: {
type: String,
// required: true,
min: 5,
},
stripeCustomerId: {
type: String,
// unique: true,
},
linkedAffiliateUser: {
type: String, //mongoose.Schema.Types.ObjectId,
},
restaurants: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Restaurant",
},
],
role: {
roleId: { type: Number, minlength: 1, maxlength: 1, required: true },
roleName: { type: String, trim: true, required: true },
},
// seperated schema
},
{ timestamps: true }
);
export default mongoose.model("User", userSchema);
and here is my Restaurant Schema:
const restaurantSchema = new Schema({
restaurantOwner: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
Name: {
type: String,
trim: true,
},
server: { type: mongoose.Schema.Types.ObjectId, ref: "ServerUser" },
restaurantLinkAccess: {
type: String,
required: true,
trim: true,
unique: true,
},
});
restaurantSchema.pre("remove", function (next) {
this.model("User")
.update(
{ restaurantSchema: this },
{ $pull: { comments: this._id } },
{ multi: true }
)
.exec(next);
});
export default mongoose.model("Restaurant", restaurantSchema);
I also tried to solve it like this:
restaurantSchema.pre("remove", function (next) {
this.model("User").remove({ $pull: { restaurants: this._id } }, next);
});
Please help.

How to use values of map function in other functions?

I want to use data returned by a map method into another function.
Here is the route schema:
const routeSchema = new mongoose.Schema(
{
Location: {
from: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
to: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
},
busId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Bus",
required: true,
},
date: {
type: String,
required: true,
},
departureTime: {
type: Number,
required: true,
},
arrivalTime: {
type: Number,
required: true,
},
},
{
timestamps: true,
}
);
and here is the booking schema and in booking table routeId is embedded:
const bookingSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
routeId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Route",
required: true,
},
passengers: [
{
name: { type: String, required: true, trim: true },
gender: { type: String, required: true, trim: true },
age: { type: Number, required: true, trim: true },
}],
phone: {
type: Number,
required: true,
},
email: {
type: String,
required: true,
},
bookingDate: {
type: String,
required: true,
},
fare: {
type: Number,
required: true,
},
seats: {
type: [Number],
required: true,
},
departureDetails: [
{
city: { type: String, required: true, trim: true },
location: { type: String, required: true, trim: true },
time: { type: String, required: true, trim: true },
date: { type: String, required: true, trim: true },
},
],
arrivalDetails: [
{
city: { type: String, required: true, trim: true },
location: { type: String, required: true, trim: true },
time: { type: String, required: true, trim: true },
date: { type: String, required: true, trim: true },
},
],
},{
timestamps:true
});
Here is the map function method:
router.get("/trip/single", async (req, res) => {
if (!req.query.from || !req.query.to || !req.query.date) {
return res.send({
error: "Please enter the data to get the trip",
});
}
const { from, to, date } = req.query;
const routes = await Route.find({
"Location.from": from,
"Location.to": to,
"date": date.toString(),
});
const matchedBus = await routes.filter(() =>{
return Route.busId === routes._id
});
const bookings = await Booking.find({
routeId: { $in: matchedBus.map((matchedBus) => matchedBus._id) },
});
console.log(bookings);
const busIdWithSeatsObj = {};
var busData = matchedBus.map(data => data)
console.log(busData);
This busData console is returning this data:
[
{
Location: {
from: new ObjectId("6295f0986f9e32990d8b3488"),
to: new ObjectId("6295f0c06f9e32990d8b348b")
},
_id: new ObjectId("6295f12c6f9e32990d8b348e"),
busId: new ObjectId("6295f0836f9e32990d8b3485"),
date: '2022-06-02',
departureTime: 11,
arrivalTime: 6.3,
createdAt: 2022-05-31T10:42:52.785Z,
updatedAt: 2022-05-31T10:42:52.785Z,
__v: 0
}
]
Now I want to use only busId and date only in the function below:
for (let i = 0; i < matchedBus.length; i++) {
let currentBusSeats = [];
const busBookings = bookings.filter((booking) => {
return (
//Want to use date and busId data in here
//someData === date.toString() &&
//someData === matchedBus[i]._id
);
});
console.log(busBookings);
busBookings.forEach(() => {
currentBusSeats = [...currentBusSeats, ...Booking.seats];
});
busIdWithSeatsObj[matchedBus[i]._id] = currentBusSeats;
}
res.status(200).send({ routes, matchedBus, busIdWithSeatsObj });
});
How can I do that to get the result?
var busData = matchedBus.map(data => data
'use your for loop inside data and you can get you _id value by data._id'
)

What is the correct way to enter an Array?

I want to enter data via Postman into an array form using id Collection in the database also how can I write a valid JSON script for the modal for the modal
Add data using id Collection
controller
const addAcademicExperience = async (req, res, next) => {
//const id = req.params.id;
const {AcademicExperience} = req.body;
let academicexperience;
try {
academicexperience = await AcademicExperience.findByIdAndadd(id, {
AcademicExperience
});
await academicexperience.save();
} catch (err) {
console.log(err);
}
if (!academicexperience) {
return res.status(404).json({ message: 'Unable to Add' })
}
return res.status(200).json({academicexperience});
model Schema
Some data is required in an array and some are not
per user per user
To clarify, the site is similar to LinkedIn
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const FacultySchema = new Schema({
Faculty_ID: {
type: Number,
required: true,
unique: true,
},
Name: {
type: String,
required: true,
},
Phone_Number: {
type: String,
required: true,
},
Email: {
type: String,
required: true,
},
AcademicExperience: [{
institution: { type: String, required: true },
rank: { type: String, required: true },
title: { type: String, required: true },
working: { type: Boolean, required: true },
}
],
Certifications:
{
type: String,
require: true,
},
Currentm_embership:
{
type: String,
require: true,
},
Servicea_ctivites:
{
type: String,
require: true,
},
Professional:
{
type: String,
require: true,
},
Education:[ {
degree: { type: String, required: true },
discpilne: { type: String, required: true },
institution: { type: String, required: true },
year: { type: Date, required: true },
}
],
Non_academic_experines:[
{
Company: { type: String, required: true },
title: { type: String, required: true },
working: { type: Boolean, required: true },
Description_of_position: { type: String, required: true },
}
],
Honoers_and_awards:
{
type: String,
require: true,
},
Puplications_and_presentation:
{
type: String,
require: true,
},
});
module.exports = mongoose.model("Faculty", FacultySchema);

How to get data from mongoDB on the basis of a value inside a nested object

Below is my API for fetching all the orders of a specific restaurant from a mongoDB database.
My search is based on the restaurant id which I am getting from params and passing it to the query object.
query1 is working but query2 does not return my data.
It is returning an empty array. If I pass a simple object in find() then I am getting a response. But when i use a nested object for getting data I get nothing.
exports.getOrders = async (req, res) => {
const restId = req.params.restId;
console.log("restaurant id", restId);
if (!restId) return res.status(404).send("No restaurant ID found in params");
const query1 = {grandTotal: 600};
const query2 = { restaurant: { restaurantId: restId } };
const response = await Orders.find(query2);
console.log("Printing response inside API function", response);
}
Below is my MongoDB Schema of Orders.
const mongoose = require("mongoose");
const orderSchema = mongoose.Schema({
customer: {
name: {
type: String,
required: true,
},
contact: {
type: String,
required: true,
},
customerId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Customer",
required: true,
},
customerAddress: {
type: String,
required: true,
},
},
restaurant: {
restaurantName: {
type: String,
required: true,
},
contact: {
type: String,
required: true,
},
restaurantId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Restaurant",
required: true,
},
},
/*date: {
day: {
type: Number,
required: true,
},
month: {
type: String,
required: true,
},
year: {
type: Number,
required: true,
},
},
type: {
type: String,
enum: ["delivery","takeaway"],
required: true,
},*/
items: [
{
itemId: { type: String, required: true },
itemName: { type: String, required: true },
itemDescription: { type: String, required: true },
price: {type: Number, required: true},
quantity: { type: Number, required: true },
total: {type: Number, required: true},
},
],
grandTotal: {type: Number, required: true},
status: {
type: String,
enum: ["pending", "rejected","cancelled","accepted","received"],
required: true,
},
});
orderSchema.virtual("booking", {
ref: "Booking",
localField: "_id",
foreignField: "orderId",
});
orderSchema.set("toObject", { virtual: true });
orderSchema.set("toJSON", { virtual: true });
const Orders = mongoose.model("Orders", orderSchema);
exports.Orders = Orders;
change query2 to this
const query2 = { "restaurant.restaurantId": restId } };

Resources