Mongoose Population issue - javascript

I'm trying to populate the records schema with users, So i can account for a user for each record. However, i am only getting a blank array back.
Here are my schemas:
1.The Records schema:
const mongoose = require('mongoose')
const RecordsSchema = new mongoose.Schema({
Title: {
type: String,
required: true
},
users: [{
type: [mongoose.Schema.Types.ObjectId],
ref: 'users'
}],
Author: {
type: String,
required: true
},
ISBN: {
type: String,
required: true
},
Review: {
type: String
},
SelectedFile: {
type: String
},
Likes: {
type: Number,
default: 0
},
Date: {
type: Date,
default: Date.now()
}
});
module.exports = Records = mongoose.model('records', RecordsSchema ');
Here is the The user Schema:
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
username: {
type: String
},
email: {
type: String,
required: true,
unique: true
},
records: [{
type: [mongoose.Schema.Types.ObjectId],
ref: 'records'
}],
password: {
type: String,
required: true
},
Date: {
type: Date,
default: Date.now,
immutable: true
}
});
module.exports = User = mongoose.model('users', userSchema);
The express route:
router.get('/all', async (req, res) => {
try {
const records = await Records.find()
.sort({ Date: -1})
.populate('users')
.exec()
res.json(records);
} catch (err) {
console.error(err.message);
res.status(404).send('Server Error');
}
});
Result:
{
"users": [],
"Likes": 0,
"_id": "5fed8c12a4fb2c1e98ef09f6",
"Title": "New Age",
"Author": "Situma Prisco",
"ISBN": "23422",
"SelectedFile": "",
"Review": "",
"Date": "2020-12-31T08:30:10.321Z",
"__v": 0
}
I'm getting a blank Array After populating. What am I doing wrong?

Related

MongoDB: how can I pull an entire object from an object array that matches the Objectid?

My question is, how I can pull a team object in teams that matches the unique _id of a team(in teams array).
Here is what I have tried, however, the problem is that all entries in teams get deleted, instead of only the object that matches the team _id.
router.put("/delete/team/:id/:org", (req, res) => {
const orgid = req.params.org;
const _id = req.params.id;
Organization.findOneAndUpdate(
{
_id: orgid,
},
{
$pull: {
teams: { _id: _id },
},
},
{ multi: true }
)
.then((organization) => {
res.status(200).json(organization);
})
.catch((err) => {
res.status(400).json(err);
});
});
Each Organization in OrganizationSchema has a unique _id.
Also, each team(object) in teams array has a unique _id.
const OrganizationSchema = new Schema({
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
register_date: {
type: Date,
default: Date.now,
},
teams: [
{
sport: {
type: String,
required: false,
},
access_code: {
type: Number,
required: false,
},
admin: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
events: [
{
date_time: {
type: Date,
offset: true,
},
opponent: {
type: String,
required: true,
},
home_away: {
type: String,
required: true,
},
expected_attendance: {
type: Number,
},
people_attending: [
{ type: mongoose.Schema.Types.ObjectId, ref: "User" },
],
amenities: [String],
},
],
},
],
});
The probable reason for the output you are getting is, because you are matching an ObjectId with a string.
You need to convert your string to an object.
You can do this by adding,
const ObjectID = require('mongodb').ObjectID
And then,
$pull: {
teams: { _id: new ObjectID(_id) },
},

MongooseJS: Having a hard time populating a list of comments

I have a schema called Post, and in the Schema, there is a comments attribute.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const PostSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users",
},
text: {
type: String,
required: true,
},
name: {
type: String,
},
avatar: {
type: String,
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: "users",
},
},
],
comments: [
{
type: Schema.Types.ObjectId,
ref: "comments",
},
],
date: {
type: Date,
default: Date.now,
},
});
module.exports = Post = mongoose.model("post", PostSchema);
Here is my Comments schema.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const CommentSchema = new Schema({
post: {
type: Schema.Types.ObjectId,
ref: "posts",
},
user: {
type: Schema.Types.ObjectId,
ref: "users",
},
text: {
type: String,
required: true,
},
name: {
type: String,
},
avatar: {
type: String,
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: "users",
},
},
],
replies: [
{
type: Schema.Types.ObjectId,
ref: "comments",
},
],
date: {
type: Date,
default: Date.now,
},
});
module.exports = Comment = mongoose.model("comment", CommentSchema);
When I print out the data accessed by a post, I get it like below:
{
"_id": "630a82d564540e7196fe4887",
"user": "6301a168783647db9f7a37c8",
"text": "For the police I say ____ you punk, reading my rights and ____ it's all junk",
"name": "e",
"avatar": "//www.gravatar.com/avatar/8fd046f9f8f50ab2903fa9fd6c845134?s=200&r=pg&d=mm",
"comments": [
"630aa7c425ae8add2b275b53",
"630a834959110e8e3305b471",
"630a83200cd98eb07fb5f543"
],
"likes": [],
"date": "2022-08-27T20:47:17.888Z",
"__v": 3
}
I have tried to populate the comments shown below but I'm getting an error:
router.post(
"/commentOnPost/",
[auth, check("text", "Text is required").not().isEmpty()],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
const user = await User.findById(req.user.id);
const post = await Post.findById(req.body.post_id).populate('comments');
let newComment = Comment({
post: post.id,
text: req.body.text,
name: user.name,
avatar: user.avatar,
user: req.user.id,
});
await newComment.save();
post.comments.unshift(newComment);
await post.save();
return res.json(await post);
} catch (err) {
errorLog(err);
res.status(500).send("Server error");
}
}
);
Sat Aug 27 2022 19:27:22 GMT-0400 (Eastern Daylight Time), -> MissingSchemaError: Schema hasn't been registered for model "comments".
Use mongoose.model(name, schema)
In your Comment schema, you named model as "comment". But in the Post schema, you referenced it as "comments".
Change your code in Post schema like this:
comments: [{ type: Schema.Types.ObjectId, ref: "comment" }],

How can I push a new object and simultaneously items to an array of that same object in MongoDB?

The problem is that I only can push the object itself, however, it won't let me push new elements to the array of the object that I want to push at the same time.
Is there another way to do it, inserting another $push to append the array, inside the object $push, doesn't work. The array "amenities" of the new object stays empty.
enter code here
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const OrganizationSchema = new Schema({
logo: {
type: String,
required: true,
},
name: {
type: String,
required: true,
unique: true,
},
admin_email: {
type: String,
required: true,
unique: true,
},
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
register_date: {
type: Date,
default: Date.now,
},
teams: [
{
sport: {
type: String,
required: false,
},
access_code: {
type: Number,
required: false,
},
admin: {
type: String,
required: false,
},
events: [
{
date_time: {
type: Date,
},
opponent: {
type: String,
required: true,
},
expected_attendance: {
type: Number,
},
amenities: [String],
},
],
},
],
});
module.exports = Organization = mongoose.model(
"organization",
OrganizationSchema
);
router.put("/create/event/:teamid", (req, res) => {
const teamid = req.params.teamid;
const { date_time, competitor, amenities } = req.body;
Organization.findOneAndUpdate(
{ "teams._id": teamid },
{
$push: {
"teams.$.events": {
competitor: competitor,
date_time: date_time,
$push: {
amenities: {
amenities,
},
},
},
},
}
)
.then((list) => {
res.status(200).json(list);
console.log(JSON.stringify(list));
})
.catch((err) => {
res.status(400).json(err);
});
});

I have a Schema with Sub Schema. I want to update particular data in the Sub Schema

this is my schema
const mongoose = require('mongoose')
const MaterialListSchema = new mongoose.Schema({
nomenclature:{
type: String,
required: true
},
national: {
type: String,
required: true
},
partnumber:{
type:String,
required:true
},
quantity: {
type: Number,
required: true
},
unit:{
type: String,
required: true
},
price: {
type: Number,
required: true
}
})
const MrrlSchema = new mongoose.Schema({
aircrafttype:{
type: String,
required: true
},
mrrlcategory:{
type: String,
required: true
},
materiallist: [MaterialListSchema]
})
const Mrrl = mongoose.model('Mrrl', MrrlSchema)
module.exports = Mrrl
this is my update code . but it will delete all the sub document on the selected and will only have remaining
Mrrl.updateOne({
'materiallist': {$elemMatch: { _id: req.params.id}}
},{
$set: { materiallist: req.body }
}).then((data)=>{
console.log(data)
})
If i understand your question, you need use arrayFilters
// it is your req.body
const newMaterial = {
nomenclature: '2'
};
const result = await MrrlSchema.updateMany({ 'materiallist': {$elemMatch: { _id: req.params.id }} },
{ "$set": { "materiallist.$[material]": newMaterial } },
{ "arrayFilters": [ { "material._id": req.params.id } ] });
Note: arrayFilters can be use only with 3.6+ mongo

How to add a new Object to a property of object in a model

let userSchema = new Schema({
email: {type: String, required: true},
password: {type: String, required: true},
name: {type: String, required: true},
phoneNumber: {type: Number, required: true},
schedule: {type: String, required: true},
courses: {type: Array, required: false}
});
I have this condition, my problem is how to add a new course to courses property but in my case course is an another object. I could update using updateOne method, but it changed 1 item but not another.
As I understand, you want to embed courses into the user model.
So you need to make this change in your user model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
let userSchema = new Schema({
email: { type: String, required: true },
password: { type: String, required: true },
name: { type: String, required: true },
phoneNumber: { type: Number, required: true },
schedule: { type: String, required: true },
courses: [
new Schema({
name: String
})
]
});
module.exports = mongoose.model("User", userSchema);
And create a course for the given user like this:
app.post("/user/:id/course", async (req, res) => {
const result = await User.findByIdAndUpdate(
req.params.id,
{
$push: {
courses: {
name: req.body.name
}
}
},
{
new: true
}
);
res.send(result);
});
When you send a request to url http://localhost:3000/user/5de2cf9323f76c207c233729/course with this body:
(Note that 5de2cf9323f76c207c233729 is an existing user _id)
{
"name": "Course 1"
}
The response will be like this, meaning the course is added to the user:
{
"_id": "5de2cf9323f76c207c233729",
"email": "abc#def.net",
"password": "123123",
"name": "Max",
"phoneNumber": 123123123,
"schedule": "sc1",
"courses": [
{
"_id": "5de2cfa723f76c207c23372a",
"name": "Course 1"
}
],
"__v": 0
}

Categories

Resources