I've created a database in MongoDB using mongoose. Although everything works fine, but when I check mongodb the name of the collection has extra 's' in its name. The collection name created is employees. What could be wrong, or is it just the naming convention of mongoose?
const mongoose = require('mongoose');
let employeeSchema = mongoose.Schema({
name: String,
email: String,
department: String,
doj: Date,
address: String
});
const Employee = mongoose.model("employee", employeeSchema);
module.exports = Employee;
It doesn't just add an extra 's' but it makes the correct plural of the name.
For Example : Mouse will be converted to mice
You can disable it by:
mongoose.pluralize(null);
Reference Link: https://github.com/Automattic/mongoose/issues/5947
So you have two options for controlling document names in mongoose.
If you just want to disable pluralization, you can do it with mongoose.pluralize(null) as in Ankit's answer.
And if you want to change your collection name whatever you want, you can do:
mongoose.model("employee", employeeSchema, { collection: 'myEmployee' } )
Related
Im trying to get this going or wondering if this is even necessary. I have a local schema I define for my user profiles. What im trying to do is write a code block that checks my local schema with what the database has. If a field is missing, add a default value.
My goal for this is to be able to add fields locally in my schema and have the database update when I add a new field.
My schema is as follows:
import mongoose, { Schema } from "mongoose";
const reqString = {
type: String,
required: true,
};
const reqNumber = {
type: Number,
required: true,
};
const userProfileSchema = new Schema({
//Discord User ID - Primary Key
_id: reqString,
wallet: reqNumber,
bank: reqNumber,
net_worth: reqNumber,
classID: reqNumber,
});
const name = "core-userprofile";
export default mongoose.models[name] ||
mongoose.model(name, userProfileSchema, name);
I have a class that pulls the user profile for the rest of the code to access. Id like a function in there that looks at the local schema, realizes there isnt classID, figures out its a type of number, and just places 0 there.
I believe from what im understanding I can use update/upsert when accessing it. Im more wondering if there is a way to sync these two and add/delete anything that doesn't match the local version.
Thanks in advance!
When the table name includes a capital letter (e.g. fooBar), Moongoose Model.find() returns an empty array. If I change both the table name and the search string to be lowercase without changing anything else - it works fine.
Is this expected?
I think I have read somewhere about collection names being treated by default as lowercase inside of mongoose. I always circumvent it by using models:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const FoobarSchema = new Schema({
name: { type: String }
}, { collection: 'fooBar' });
module.exports = mongoose.model('fooBar', FoobarSchema);
The important part is what you name the collection in the Schema definition. In the export that 'fooBar' can be named whatever you want and is a means to reference the model in your code.
I'm fairly new to this, so bear with me, however I have 2 collections. One called photos and another called users.
In Node, I am taking the data and putting it into my MongoDB using mongoose. I've got this working fine with my Schema:
var picSchema = new Schema({
uid: String,
pid: String,
oFile: String
});
What I want to do though is for the uid, I want to add the ObjectId for the user uploading the photo. I can pass this as a String, however I thought that I would have had to have the field set as an ObjectId, but seems I cannot do this?
Unless I am missing something, I might as well just add the username in there and use that as a reference?
Use mongoose.Schema.Types.ObjectId to populate the field with an ObjectId. In this case, you would use User (or whatever the name of your User schema is).
var picSchema = new Schema({
uid: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
pid: String,
oFile: String
});
Further to this, you can also use the Mongoose method Populate if you wish to expand the User document within a Pic document. For example:
Pic.find({})
.populate('uid')
.exec(function(err, pic) {
console.log(pic);
// do something
});
Say I have a collection that contains a field that references documents from another collection like follows:
ClassEnrollment
_id | student | class
---------------------
and classes in the Class collection have the following schema:
_id | className | teacher | building | time | days | classNumber | description
------------------------------------------------------------------------------
If I have a set of 3000 classes I want to populate on the server I might do something like ClassEnrollment.populate(listOfClassEnrollments, {path: 'class'});
In my situation, I don't want the majority of the class fields though, just the name. If I get the list of 3000 classes from the db with all fields, I end up taking a performance hit in the form of network latency (these 3000 classes have to be transferred from the hosted db to the server, which might be 50 MB of raw data if the descriptions are long)
Is there a way to populate the list of class enrollments with just the name through an option to populate (behind the scenes I imagine it would work like a projection, so the db just responds with the class name and _id instead of all the class information)?
You can use the select option in your populate call to do this:
ClassEnrollment.populate(listOfClassEnrollments, {path: 'class', select: 'className'});
To specify multiple fields, use a space-separated list:
ClassEnrollment.populate(
listOfClassEnrollments,
{path: 'class', select: 'className classNumber'}
);
Let's say we have a very simple user & video schemas.
1) USER SCHEMA
import mongoose from "mongoose";
const { Schema, model } = mongoose;
const UserSchema = new Schema({
name: String,
email: String,
password: String,
});
export default model("User", UserSchema);
2) VIDEOS SCHEMA
import mongoose from "mongoose";
const { Schema, model } = mongoose;
const { ObjectId } = Schema.Types;
const VideoSchema = new Schema({
videoOwnerId: { type: ObjectId, ref: "User", required: true },
title: { type: String, required: true },
desc: { type: String, required: true },
});
export default model("Video", VideoSchema);
Then I want to find in Videos Collection all videos by specific user AND at the same time all information about this user(a user document from Users Collection) and use projection on it ( select specific fields )
3) Somewhere in our code (maybe in a controller)
const videos = await Video.find({ videoOwnerId: "someId214121" }).populate("videoOwnerId", "-password");
So to populate with projection you use a populate("videoOwnerId", "-password") method, when the first argument is a field you want to populate, the second argument is a projection.
To get a document with all fields but without password for example
populate("videoOwnerId", "-password")
To get only specific fields that you want(string with fields separated by whitespace)
populate("videoOwnerId", "name email")
I use mongoose in my node.js app, and basically have the following models:
// Define Car model
CarSchema = new Schema({
brand : String,
type: String,
maxSpeed : Number
});
mongoose.model('Car', CarSchema);
// Define User model
UserSchema = new Schema({
lastname : String,
firstname : String,
cars : [CarSchema]
});
mongoose.model('User', UserSchema);
I'm really new to NoSQL and I really want to give it a try but I first need to study if this really fits my needs.
With the above models, will I be able to create a query listing all the Users who have a particular type of car among their personal cars ?
I don't how to do it in mongoose. But in mongodb it possible. So, in mongodb shell query will looks like this:
db.users.find({"cars.type":"sport"})
Above query return all users thats have car with type 'sport' in their nested collection of cars.
Mongodb dot notation documentation.