MongoDB Create New Document that references another Collection's Document IDs - javascript

I am trying to create a new document in the Form collection. This document references many FormSection documents. Here are the Schemas:
const FormSchema = new Schema({
title: {
type: String,
required: true,
unique: true
},
description: {
type: String,
required: true,
unique: true
},
sections: [{
type: FormSectionDetails
}],
createdDate: {
type: String,
required: false,
unique: true
},
lastEdited: {
type: String,
required: false,
unique: true
}
});
const FormSectionDetails = new Schema({
section: {
type: Schema.Types.ObjectId,
ref: 'FormSection',
required: true
},
position: {
type: Number,
required: true
}
});
const FormSectionSchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
display: {
type: String,
required: true,
},
category: {
type: String,
required: true
},
...
});
let FormSection;
try {
FormSection = mongoose.connection.model('FormSection');
} catch (e) {
FormSection = mongoose.model('FormSection', FormSectionSchema);
}
However, when I try to add a new document to the Forms collection, I get an error:
Document being inserted:
formData = {
"title": "Returning Members",
"description": "Returning Members",
"sections":
[{
"section": "6292c0fbd4837faca1d85d4d",
"position": 1
},
{
"section": "6292c0fbd4837faca1d85d4e",
"position": 2
},
...
}
Code being run:
formdata.sections.map(s => {
return {
...s,
section: ObjectId(s.section),
}}
);
return await FormSection.create(formdata);
Error message:
ValidationError: category: Path `category` is required., display: Path `display` is required.````
Seems like it is trying to create a new FormSection document. I don't want it to create a new FormSection document. I just want it to reference existing FormSection documents using the Object IDs I specified.

The Issue seems to be with how you declare the section field in the FormSchema. Try this:
const FormSchema = new Schema({
title: {
type: String,
required: true,
unique: true
},
description: {
type: String,
required: true,
unique: true
},
sections: [{
type: ObjectId,
ref: 'FormSectionDetails',
required: true,
}],
createdDate: {
type: String,
required: false,
unique: true
},
lastEdited: {
type: String,
required: false,
unique: true
}
});
This would just store the _ids of the existing FormSectionDetails

It turns out I was inserting the document into the wrong collection. Instead of the code snippet:
return await FormSection.create(formdata);
It should actually be:
return await Form.create(formdata);
The error message should have been a more obvious hint for me as to what the problem was.

Related

Mongoose: Check if value exists in string array

I am querying to get all articles that have a specific source name and category.
I have an article schema that looks like below.
The issue I'm facing is that, it fetches the articles with the correct source name, but it doesn't fetch for the right category. For example, if source is "cnn" and category is "sports", it fetches all articles from CNN correctly, but not with correct categories (the articles may have a categories of ['politics', 'culture'] with no sports)
const article_schema = new mongoose.Schema({
title: {
type: String,
required: true
},
thumbnail_url: {
type: String,
required: true
},
summary: {
type: String,
required: true
},
text: {
type: String,
required: true
},
link: {
type: String,
required: true
},
publish_date: {
type: String,
required: true
},
source: {
name: {
type: String,
required: true
},
name_slug: {
type: String,
required: true
},
link: {
type: String,
required: true
},
display_picture_url: {
type: String,
required: true
},
biography: {
type: String,
required: true
},
tags: {
type: [String],
required: true
},
rssFeeds: [{
url: {
type: String,
required: true
},
categories: {
type: [String],
required: true
}
}]
}
});
let getNews = async (req, res) => {
const { sort, filter, current_page, limit, category_slug } = req.body;
let articles = await Article.findOne({ 'source.name_slug': filter, categories: category_slug });
res.setHeader('Content-Type', 'application/json');
res.status(200).send({ articles });
}

Node Populate Array with object reference

I need to Populate courses of StudentSchema with the courses (Object_id) from CoursesSchema that belong to the major same as students major
let StudentSchema = new Schema({
_id: new Schema.Types.ObjectId,
emplId: {
type: Number,
required: true
},
major:{
type: String,
required: true
},
courses:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'courses',
grade:{
type: String,
required: false,
}
}],
});
const courseSchema = new mongoose.Schema({
code: {
type: String,
required: true
},
title: {
type: String,
required: true
},
//array of majors that a courses is required for e.g: ['CS', 'CIS']
major: {
type: Array,
required: false,
},
//
CIS:{
type: Boolean,
required: false,
},
CNT:{
type: Boolean,
required: false,
},
CS:{
type: Boolean,
required: false,
},
GIS:{
type: Boolean,
required: false,
},
})
What do I do?
StudentCoursesRouter.get('/studentcourses', (req, res) => {
Courses.find({CS: true}, (err, courses) => {
if ( err ) {
console.log('Error occured while getting records');
res.json(err);
} else {
courseMap = {}
courses.forEach(function(course) {
courseMap[course._id] = course._id;
});
//res.send(courses);
Students.find({empleId: 12345678}).courses.push(courses);
}
res.json(Students);
})
This is what i am doing but it is not populating courses of student and gives an empty array for courses.
API Request Response Screenshot
You mention populate but you are not using populate?
e.g. Students.find({empleId: 12345678}).populate('course')
If you want it lean u also need to install mongoose-lean-virtuals
e.g. Students.find({empleId: 12345678}).populate('course').lean({ virtuals: true })

Updating count of individual sub document that's in an array of a mongo document

So the example right now is for the User table.. I have a UserWeapon document embedded that is an array of all the weapon's a user has and how many kills they have with the weapon. I want to write a query that when given the userId, weaponId, and new kills, it'll update the sub document accordingly.
So something like
const user = await User.findById(userId);
const userWeapon = await user.userWeapon.findById(weaponId);
userWeapon.kills = userWeapon.kills + newAmmountOfKills
user.save();
What would be the most efficient way to do this?
Schemas:
const UserWeaponSchema = new Schema({
weapon: { type: Schema.Types.ObjectId, ref: 'Weapon' },
user: { type: Schema.Types.ObjectId, ref: 'User' },
kills: {
type: Number,
required: true,
unique: false,
},
deaths: {
type: Number,
required: true,
unique: false
},
equippedSkin: {
type: Schema.Types.ObjectId, ref: 'WeaponSkin',
required: false,
},
ownedWeaponSkins: [{ type: Schema.Types.ObjectId, ref: 'WeaponSkin'}]
});
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
weapons: [{
type: Schema.Types.ObjectId, ref: 'UserWeapon'
}],
});
You can use $inc operator and run update operation, something like:
UserWeaponSchema.update({ weapon: weaponId, user: userId }, { '$inc': { 'kills': newAmmountOfKills } })

I am getting E11000 duplicate key error collection: restauracja.tables index: reservations.user.email_1 dup key: { : null }

This is my Table Collection:
const tableSchema = new Schema({
number: {
type: Number,
required: true,
unique: true
},
seats: {
type: Number,
required: true
},
reservations: [orderSchema]
})
const Table = mongoose.model('Table', tableSchema)
And OrderSchema:
const orderSchema = new Schema({
time: {
type: String,
required: true
},
date: {
type: String
},
user: userSchema
})
And User Collection and Schema:
const userSchema = new Schema({
firstname: {
type: String,
required: true
},
lastname: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
phone: {
type: String
},
password: {
type: String,
required: true
},
admin: {
type: Boolean,
default: false,
required: true
}
})
const User = mongoose.model('User', userSchema)
When i would like to create the second (i have no idea why first is adding) instance of table, i am getting error like in title:
MongoError: E11000 duplicate key error collection: restauracja.tables index: reservations.user.email_1 dup key: { : null }
I can create only one document in table, but i have different values in the second one.

Updating nested array's field

I have a schema
const RoomSchema = mongoose.Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
},
author: {
type: String,
required: true
},
resource: {
type: String
},
posts: {
type: Array,
default: []
},
url: {
type: String
},
created_at: {
type: String,
required: true
}});
Field 'posts' is another document in my db, defined by the following schema:
const PostSchema = mongoose.Schema({
header: {
type: String,
required: true
},
body: {
type: String,
required: true
},
author: {
username: {type:String, required: true},
_id: {type:String, required:true}
},
room: {
type: String,
required: true
}});
So, I'm trying to create a query that would update fields of certain post inside posts array inside room. I've already tried suggested here, thought without results. I would appreciate any help on the subject
Room.update({ '_id': roomId, 'posts._id': postId },
{ $set: { 'posts.$.header': newHeader, 'posts.$.body': newBody } },
callback);

Categories

Resources