Populate returns whole parent document - node.js

I just started learning express and mongodb. I recently faced the kind of problem, I'm trying to select all the subdocuments which are inside of Room model.
const books = await Room.find().populate('book');
But it returns whole room document when i want to select only bookings field.
Here's the book schema
const bookSchema = new mongoose.Schema({
startDate: {
type: Date,
required: true,
},
endDate: {
type: Date,
required: true,
},
name: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
});
module.exports = mongoose.model("book", bookSchema)
And here's the room schema
const roomSchema = new mongoose.Schema({
currentlyReserved: {
type: Boolean,
default: false,
},
people: {
type: Number,
required: true,
},
roomNumber: {
type: Number,
required: true,
},
pricePerPerson: {
type: Number,
required: true,
},
reservedUntil: {
type: Date,
default: null,
},
reservedBy: {
type: String,
default: null,
},
bookings: {
type: [{ type: mongoose.Schema.Types.ObjectId, ref: "book" }],
},
});
module.exports = mongoose.model("room", roomSchema);

You can project with with second arg to find().
https://docs.mongodb.com/manual/reference/method/db.collection.find/#projection
const books = await Room.find({}, {bookings: 1}).populate('bookings');

Related

How to update a specific object in a array of objects by Item ID in Node.js and Mongoose

I need a code in Express.Js and Mongodb where I can change an exact string inside an object through the id of the item, I need to change the string "colorSelected" to a new value, changing only what I put in the body, in my previous failed attempts every change I made would change the entire object, I don't want that, thank you in advance.
Router Cart.js
//update color cart
router.patch("/cart/:id", Auth, async (req, res) => {
});
Model Cart.js
const mongoose = require('mongoose')
const ObjectID = mongoose.Schema.Types.ObjectId
const cartSchema = new mongoose.Schema({
owner : {
type: ObjectID,
required: true,
ref: 'User'
},
items: [{
itemId: {
type: ObjectID,
ref: 'Item',
required: true
},
img: String,
name: String,
colorSelected: String,
colors: Array,
stock: Number,
quantity: {
type: Number,
required: true,
min: 1,
default: 1
},
price: Number
}],
bill: {
type: Number,
required: true,
default: 0
}
}, {
timestamps: true
})
const Cart = mongoose.model('Cart', cartSchema)
module.exports = Cart
Model Item.js
const mongoose = require('mongoose')
const ObjectID = mongoose.Schema.Types.ObjectId
const reviewSchema = mongoose.Schema(
{
name: { type: String, required: true },
rating: { type: Number, required: true },
comment: { type: String, required: true },
user: {
type: ObjectID,
required: true,
ref: 'User'
},
},
{
timestamps: true,
}
)
const itemSchema = new mongoose.Schema({
images: [{
name: {
type: String,
required: true
},
src: {
type: String,
required: true
},
color: {
type: String,
required: true
},
}],
owner : {
type: ObjectID,
required: true,
ref: 'User'
},
name: {
type: String,
required: true,
trim: true
},
description: {
type: String,
required: true
},
category: {
type: Number,
required: true
},
price: {
type: Number,
required: true
},
stock: {
type: Number,
required: true
},
visibility: {
type: Boolean,
required: true
},
reviews: [reviewSchema],
rating: {
type: Number,
required: true,
default: 0,
},
numReviews: {
type: Number,
required: true,
default: 0,
}
}, {
timestamps: true
})
const Item = mongoose.model('Item', itemSchema)
module.exports = Item

How to receive information from a model inside an array in another model? (mongoose)

I have a "cart" model, and within my "order" model, I would like to have an array that receives the information sent by "cart" stored in an array. How can I do this through ref?
const mongoose = require('mongoose');
const CartSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
note: {
type: String,
required: true,
},
price: {
type: Number,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Cart", CartSchema);
order
const mongoose = require('mongoose');
const OrderSchema = new mongoose.Schema(
{
list: {
name: String,
notes: String,
},
totalAmount: {
type: Number,
required: true,
},
payment: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
addressNote: {
type: String,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Order", OrderSchema);
Here in "list" I would like it to be an array that receives cart model information
Can I do this through ref? What would be the best possible way?

How to 'join' or populate an array

Here is my very basic product schema:
const productSchema = new Schema({
productName: {
type: String,
required: true,
},
productDescription: {
type: String,
},
productPrice: {
type: Number,
},
});
module.exports = mongoose.model("Product", productSchema);
These products are listed out and a user can add a quantity for each. I am storing in an array of objects as per below. I want to join these two collections together so that I can output the qty of products selected by the user. I believe I need to use populate here but not sure how to set up the Refs and so on.
const PartySchema = new Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
catering: [{ id: mongoose.Types.ObjectId, qty: Number }],
created_at: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Party", PartySchema);
I'm sharing this solution with the assumption that the catering field is the sub-document array pointing to the Product Schema:
The Product Schema is fine so it stays the same (although to keep to convention I would advice naming your schema 'Products' instead of 'Product', Mongo Naming Covention):
const productSchema = new Schema({
productName: {
type: String,
required: true,
},
productDescription: {
type: String,
},
productPrice: {
type: Number,
},
});
module.exports = mongoose.model("Products", productSchema);
And next the Party Schema would be:
const PartySchema = new Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
catering: [{
id: {
type: mongoose.Types.ObjectId,
ref: 'Products',
},
qty: {
type: Number,
}
}],
created_at: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Parties", PartySchema);

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 } };

Node JS and Mongoose How to get data from 2 collections?

I need to get all docs from service collection and it's showing all records when i console content. In content collection there is field mids which is media id and all images are going to media collection. I need to get media url for specific service. But when i console content.mids it returns undefined .Do i need to change in query?
Code is attached for your reference.
// Controller
services: (req, res) => {
Posts.find({content_type:'service'}).then(function(content) {
console.log(content); //right
console.log(content.m_ids); //showing undefined
Media.findById(content.m_ids).then(media => {
res.render('default/services', {content: content, reqUrl: req.url});
});
})
}
Services Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Schema = new Schema({
content_type: {
type: String,
required: true,
maxlength:20
},
content_title: {
type: String,
required: true,
max:100
},
content_url: {
type: String,
required: true,
maxlength:200
},
content_description: {
type: String,
required: true,
},
content_full_description: {
type: String,
required: false,
},
pt_ids: {
type: String,
required: false,
},
pc_ids: {
type: String,
required: false,
},
m_ids: {
type: String,
required: false,
},
created_by_user_id: {
type: String,
default: 1,
},
created_on: {
type: Date,
default: Date.now
},
updated_on: {
type: Date,
default: Date.now
},
post_icon_svg: {
type: String,
required: false,
}
});
module.exports = {Posts: mongoose.model('content_data', PostsSchema )};
// Media Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const MediaSchema = new Schema({
media_name: {
type: String,
required: true
},
media_title: {
type: String,
required: true
},
media_alt: {
type: String,
required: true
},
media_description: {
type: String,
required: false
},
media_url: {
type: String,
required: true,
unique: true
},
created_by_user_id: {
type: String,
default: 1,
},
created_on: {
type: Date,
default: Date.now
},
updated_on: {
type: Date,
default: Date.now
}
});
module.exports = {Media: mongoose.model('media', MediaSchema )};

Resources