mongoose doesn't allow me to use camelCase collection name - node.js

Here is my code:
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/miniRDS",{
useNewUrlParser:true,
useCreateIndex:true,
useUnifiedTopology: true
},(err)=>{
if(!err){
console.log("Connected")
}else{
console.log("Couldn't connect!");
}
});
const tests = new mongoose.Schema({
subject:{
type:String,
required:true,
default:"ict"
},
date:{
type:String,
required:true,
default:"01-01-2021"
}
});
const testsModel = mongoose.model("classTests",tests);
const s = new testsModel({
subject:"english",
date:"12-01-2021"
});
s.save();
I am using mongoose version 5.11.11. And I am facing difficulty when I try to create a collection with camelCase name using mongoose model.
In the above codes, It should create a collection name "classTests", instead it creates "classtests". how can I achieve "classTests"? Thanks

you can use it as:
module.exports = mongoose.model("user_notification_preference", NotificationPreference, "userNotificationPreferences");
three parameters:(the name you want to use as camel, schema, the actual name)

Mongoose automatically looks for the plural, lowercased version of your model name,
please check this documentation, so you can't create a collection with camelCase in mongoose

Solution :
To Resolve this, We can use a Plural name in the collection field
const mongoose = require('mongoose');
const AssessmentAttemptSchema = new mongoose.Schema(
{
userId: {
type: mongoose.Types.ObjectId,
required: true,
},
verificationToken: {
type: String,
required: true,
unique: true,
},
},
{
timestamps: true,
collection: "assessmentAttempts",
}
);
module.exports = mongoose.model('AssessmentAttempt', AssessmentAttemptSchema);
So for this case, we are using assessmentAttempts to save the collection name as CamelCase.
End Result:
Mongo DB : Sample Collection
MongoDB Collection Name Restrictions Docs : Reference Link

Related

No Mongoose db showing up after using mongoose.connect and creating a mongoose model

Hello I am trying to connect a mongoose database to my project using Node js, Express and Mongoose and I have run into a weird problem. After connecting to a mongoose database successfully and specifying a model, nothing seems to show up in my collections (i.e no schemas). However when I do the command use "my new database" it switches to that database. I have looked all over the place and cannot seem to find the issue and I'm pretty sure my code is correct. Below is my code
importing model and creating database:
const Item = require("./models/Item"),
mongoose.connect("mongodb://localhost:27017/SurfShareDB", {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Your Database has been connected");
})
.catch((err) => {
console.log("ERROR", err.message);
});
Item schema and model:
const mongoose = require("mongoose");
const itemSchema = new mongoose.Schema({
title: String,
image: String,
description: String,
price: String,
created: { type: Date, default: Date.now },
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
},
username: String,
},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment",
},
],
});
module.exports = mongoose.model("Item", itemSchema);
A collection in MongoDB is not created until something is written to either a document in the collection, an index on the collection, or to the collection's metadata.

Can I set a element of my mongoose model to be strictly of some particular other models?

My subsection model should strictly be a type of lecture or quiz model only.
I want something like this. Any idea how to implement it properly?
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const subSectionSchema = new mongoose.Schema({
subSection:{
type:ObjectId,
enum:["Lecture","Quiz"]
}
});
module.exports = mongoose.model("SubSection", subSectionSchema);
Although I can always do this way...check which type it is and set that value.
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const subSectionSchema = new mongoose.Schema({
lecture: {
type: ObjectId,
ref: "Lecture",
},
quiz: {
type: ObjectId,
ref: "Quiz",
},
});
module.exports = mongoose.model("SubSection", subSectionSchema);
But I am looking for something simple.
I'm not sure if I understood your question, but I think what you're looking for are dynamic references. This feature allow us to have dynamic properties on our MongoDB collection.
You'll basically need two properties for it, one for the ObjectID, other for the reference. Whenever you need to populate the reference, it will automatically detects which entity/collection to use.
Here's a quick example from Mongoose docs:
const commentSchema = new Schema({
body: { type: String, required: true },
on: {
type: Schema.Types.ObjectId,
required: true,
// Instead of a hardcoded model name in `ref`, `refPath` means Mongoose
// will look at the `onModel` property to find the right model.
refPath: 'onModel'
},
onModel: {
type: String,
required: true,
enum: ['BlogPost', 'Product']
}
});
const Product = mongoose.model('Product', new Schema({ name: String }));
const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
const Comment = mongoose.model('Comment', commentSchema);

Mongoose schemas cast error when adding a new category

I have two schemas, one collection and another category. A collection has many category and a category can have many collection items.
I'm looking to create a filter later on down the line.
category schema
const mongoose = require('mongoose')
let categorySchema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true
},
collections: [{ type: mongoose.Types.ObjectId, ref: 'Collection' }]
})
module.exports = mongoose.model('category', categorySchema)
collection schema
const mongoose = require('mongoose')
let collectionSchema = new mongoose.Schema({
...
categories: [{
type: mongoose.Schema.Types.ObjectId, ref: 'categories',
required: true
}]
})
module.exports = mongoose.model('collection', collectionSchema)
truncated this to keep it relevant.
I'm not looking to populate the references yet as I'm only doing the backend for now, so I'm only rendering JSON for now.
I can create multiple category
and I can create a collection with a category as a collection must have at least one category
I can edit a collection and add a new category
However, sometimes I seem to get the following error
I'm not sure why maybe the database hasn't updated in the app, I am using nodemon so I'm not really sure what the issue could be here.
const CollectionSchema = new Schema({
name: String
categoryName: String
});
const CategorySchema = new Schema({
name: String
});
CollectionSchema.virtual('category', {
ref: 'Category', // The model to use
localField: 'name', // Find people where `localField`
foreignField: 'categoryName', // is equal to `foreignField`
// If `justOne` is true, 'members' will be a single doc as opposed to
// an array. `justOne` is false by default.
justOne: false,
options: { sort: { name: -1 }, limit: 5 } //you can add options as well
});
const Category = mongoose.model('Category', CategorySchema);
const Collection = mongoose.model('Collection', CollectionSchema);
Collection.find({}).populate('category').exec(function(error, categories) {
/* `categories.members` is now an array of instances of `Category` */
});
This link has additional Information

Mongoose not populating array in Mongodb

Here is my Game Schema :
var mongoose = require('mongoose');
const GameSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
publishers: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Publisher'
}
]
});
var GameModel = mongoose.model('Game', GameSchema);
module.exports = GameModel;
Here is my Publisher Schema :
var mongoose = require('mongoose');
const PublisherSchema = new mongoose.Schema({
companyName: {
type: String,
required: true
},
firstParty: {
type: Boolean,
required: true
},
website: {
website: String,
}
});
var PublisherModel = mongoose.model('Publisher', PublisherSchema);
module.exports = PublisherModel;
I have a picture of what you can find in my collection "games" in mongoDB :
When I use this route :
router.get('/games', async function(req, res) {
const games = await Game
.find()
.populate('publishers')
.select('title publishers')
res.json(games);
})
I have empty arrays as result for the publishers. If I don't use an array in Schema, this is correcly populated and I got data of publisher into each game. So why mongoose doesn't populate when it is an array?
Check below by modifying the schema definition as below
I think the below could fix your issue, please give a try by redefining the publishers as below
Publishers: [
publisher: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Publisher'
}
]
I think the definition of schema is more about to define the structure of the object that we would like to process, rather about the number of objects that we want to process.
The Schema definition with what I know is defining the semantics of the model and to take advantage of the middle ware functionalities.
You can save multiple objects of which meet the same semantic definition but the definition itself cannot be an array
Thanks
Pavan

Can a subdocument be required in mongoose?

Is it possible to have nested schemas in mongoose and have a required validator on the children? Something like this:
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
}
});
const eventSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
host: {
type: userSchema,
required: true
}
});
I can't find anything in the documentation. Thanks.
Yes, your schema is correct.
The docs for mongoose nested schema (SubDocuments) can be found here
i suppose you'll update eventSchema with subdocuments of type user model.
you can use { runValidators: true} for update.
eventModel.update({ name: 'YOUR NAME' }, { $push: { host: user } }, { runValidators: true}, function(err) {
})
You can use the nested schema in mongoose.
It will also give you he Object Id on each sub schema values as well.
Doc: Here
Example: Here
required is a validator added to a schema or subschema in Mongoose (from docs)
so yes, you can set the required field to true ( it is false by default) for your subschema or subdocument in Mongoose.
The example schema you have created is correct.

Resources