Model automatically saves into a " (modelname)+s " collection - javascript

I'm using mongoose (last version , fresh install) for a MEAN architecture (mongo+express+angular+nodejs) and i'm approaching to save some data into my mongodb.
I have a db called "cogestione" and three collections: "ragazzi", "sedi" and "corsi".
I want to save a data of type Ragazzo in collection "ragazzi". I connect with:
mongoose.connect("mongodb+srv://admin:************.mongodb.net/cogestione?retryWrites=true", { useNewUrlParser: true })
.then(() => console.log("Connection to database correctly happened"))
.catch((err) => console.log(err))
and all goes smoothly. In another file i have the model:
const mongoose = require("mongoose");
const postSchema = mongoose.Schema(
{
nome: {
type: 'String'
},
cognome: {
type: 'String'
},
classe: {
type: 'String'
},
email: {
type: 'String'
}
}
);
module.exports = mongoose.model("ragazzo" , postSchema);
and i export it with the last line. Then , back in the app i send it to the db with:
const post = new Ragazzo({
nome: req.body.nome,
cognome: req.body.cognome,
classe: req.body.classe,
email: req.body.email
});
console.log(post);
post.save()
.catch((err)=>{console.log(err)});
res.status(201).json({message : "Post added"});
The problem is that it doesn't save my doc into "ragazzi" collection , but it creates a new collection called "ragazzos"... how can i tell mongoose to save it into a fixed collection?

Create your mongoose Schema like as bellow.
const mongoose = require("mongoose");
const postSchema = mongoose.Schema(
{
nome: {
type: 'String'
},
cognome: {
type: 'String'
},
classe: {
type: 'String'
},
email: {
type: 'String'
}
}, {collection: 'ragazzi'});

your problem is you use this line
module.exports = mongoose.model("ragazzo" , postSchema);
but not export the compiled model.. you should export the compiled model like this
const Post = module.exports = mongoose.model("ragazzo" , postSchema);
then in your router import it like so
const post = require("./models/Post"); // in your case keep your file path
const post = new Post({
nome: req.body.nome,
cognome: req.body.cognome,
classe: req.body.classe,
email: req.body.email
});
console.log(post);
post.save()
.catch((err)=>{console.log(err)});
res.status(201).json({message : "Post added"});
this will work the way you want it mate .. cheers

Related

how to stop mongoose from writing schema defaults when using find? [Edited]

I have defined these three models in mongoose:
const clientSchema = new mongoose.Schema({
name: String,
role: String,
age: {
type: Number,
default: 10
}
})
clientSchema.pre('save', function(){
const doc = this
doc.role = 'client'
})
const adminSchema = new mongoose.Schema({
name: String,
role: String,
})
adminSchema.pre('save', function(){
const doc = this
doc.role = 'admin'
})
const userSchema = new mongoose.Schema({
name: String,
role: String,
age: {
type: Number,
default: 10
},
})
const AdminModel = mongoose.model('AdminModel', AdminModel, 'users')
const ClientModel = mongoose.model('ClientModel', ClientModel, 'users')
const UserModel = mongoose.model('UserModel', UserModel, 'users')
and I have the following route in my express app:
app.route('/users').get(async(req, res, next)=>{
const docs = UserModel.find({ role: 'admin' })
})
It works as expected, except that it's returning the following to the client-side:
{
"name": "James Breakers",
"role": "admin",
"age": 10
}
and this is wrong, and it causes many problems.
On write, it works great, it saves it in the database without the age: 10, but the problem is when retrieving (reading) from the database, Mongoose is setting the field age: 10.
and All of that is only because I used the UserModel to retrieve that admin. But I don't want that default behavior of Mongoose at all.
How can I disable it? is there a schema option for that?

How to auto delete ObjectId referances in mongodb

im trying to auto delete notifications referance from users ,when notification gets deleted
the userSchema looks like
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
notifications: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Notification",
},
],
});
module.exports = mongoose.model("User", userSchema);
The notification model looks like this
const mongoose = require("mongoose");
const notificationSchema = new mongoose.Schema({
type: String,
created: {
type: Date,
default: Date.now,
},
});
notificationSchema.pre("deleteOne", function (next) {
this.model("User").deleteOne({ notifications: this._id }, next);
});
module.exports = mongoose.model("Notification", notificationSchema);
when i try to delete notification i get an error ,which looks like
ObjectParameterError: Parameter "obj" to Document() must be an object, got User
also is there a way to auto delete it [referances of notification in user] using TTL for notifications
ok ,after a few try and error. I came up with this solution..
const mongoose = require("mongoose");
const notificationSchema = new mongoose.Schema({
type: String,
created: {
type: Date,
default: Date.now,
},
});
notificationSchema.pre("deleteOne", function (next) {
let id = this.getQuery()["_id"];
mongoose.model("User").findOne(
{
notifications: id,
},
(err, res) => {
const index = res.notifications.findIndex((x) => x._id == id);
res.notifications.splice(index, 1);
res.save();
next();
}
);
});
module.exports = mongoose.model("Notification", notificationSchema);
Can i make any improvements ?

Add new mongoDB document with object type

I'm totally new to mongoDB, just coming from MySQL, so I'm trying to add a new document to a mongo database in Node.js, I have the code working except when I have to include a custom object.
Here's my code:
router.post('/', async (req, res) => {
const book= new Book({
title: req.body.book.title,
year_published: req.body.book.year_published,
author: req.body.author // ==> here is the problem without it works fine (comes the full author via body parameter)
});
try {
const savedBook = await book.save();
res.json({
insertedBook: savedBook
});
} catch (err) {
//console.log("Error:" + err);
res.json({error: err});
}
});
The book and author models (simplified):
// ======= AUTHORS ================ //
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate-v2');
const schema = new mongoose.Schema({
name: {
type: String,
required:true
},
place_birth: {
type: String,
required:true},
});
schema.plugin(mongoosePaginate);
const Authors = mongoose.model('Authors',schema);
module.exports = Authors;
// ======= BOOKS ================ //
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate-v2');
var ObjectId = mongoose.Schema.Types.ObjectId;
const schema = new mongoose.Schema({
title: {
type: String,
required:true
},
year_published: {
type: String,
required:true},
author: [{
type: ObjectId,
ref: 'Authors',
required:false
}],
});
schema.plugin(mongoosePaginate);
const Books = mongoose.model('Books',schema);
module.exports = Books;
Data posting:
{
"book": {
"title": "Entrada con cuernos",
"year_published": "2020",
},
"author": {
"name": "Marcus",
"place_birth": "Moscow",
}
}
What's the proper way to insert a book document?
Thanks
When creating a new Book, Book.author should be a mongoose document, meaning the Author should exist in the mongoDB already.
You need to first save the Author in the DB, then pass it in Boot.author with it's Author._id property set
P.S.: Use singular words when describing your collections:
const Authors = mongoose.model('Authors',schema);
const Authors = mongoose.model('Author',schema); // recommended
mongoose will take care of the plural naming
The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural, lowercased version of your model name

Can't import one of my mongo schema file order.js (model) in a javascript file user.js (controller)

I am trying to import a schema file(order.js) inside user.js from "models" folder.
My application gets crashed after saving user.js, it throws an error as follows,
"TypeError: Invalid value for schema path product.type, got value "undefined""
In user.js, I have imported order.js as follows,
const User = require("../models/user");
const Order = require("../models/order"); //Throws error on this line.
But when I comment require("../models/order") line, app starts to perform well.
This is my multiple Schema file (order.js):
const mongoose = require("mongoose");
const { Objectid } = mongoose.Schema;
const productCartSchema = new mongoose.Schema({
product: {
type: Objectid,
ref: "Product",
},
name: String,
count: Number,
price: Number,
});
const ProductCart = mongoose.model("ProductCart", productCartSchema);
const orderSchema = new mongoose.Schema(
{
products: [productCartSchema],
transactionid: {},
address: String,
amount: { type: Number },
updated: Date,
user: {
type: Objectid,
ref: "User",
},
},
{ timestamps: true }
);
const Order = mongoose.model("Order", orderSchema);
module.exports = { Order, ProductCart };
I have found a solution on this issue.
The ObjectId in my order.js is not defined. I just replaced it with mongoose.Schema.Types.ObjectId
This solved my issue.

Building API for model that has referenced attribute

so my question is how can i display data of a model that has an attribute reference to another model? In this task i have Driver model that has attribute state which should reference another model called State that has a name attribute. I know hot to reference models in mongoose but i don't know how to build API for creating new Driver and displaying it.
Below is my Driver and State models
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Driver = new Schema({
name: {
type: String
},
phone: {
type: String
},
email: {
type: String
},
deleted: {
type: Boolean
},
state: {
type: Schema.ObjectId,
Ref: 'State'
}
});
module.exports = mongoose.model('Driver', Driver);
This is model of State
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let State = new Schema({
name: {
type: String
}
});
module.exports = mongoose.model('State', State);
Currently my API are looking like this
driverRoutes.route('/').get(function(req, res){
Driver.find(function(err, drivers){
if(err){
console.log("Error");
} else {
res.json(drivers);
}
});
});
driverRoutes.route('/:id').get(function(req, res){
let id = req.params.id;
Driver.findById(id, function(err, temp){
res.json(temp);
});
});
driverRoutes.route('/add').post(function(req, res){
let temp = new Driver(req.body);
temp.save()
.then(temp =>{
console.log(temp.state);
res.status(200).json({'driver': 'driver added successfully'});
})
.catch(err => {
res.status(400).send('adding new driver failed');
});
});
Route with / is to display all Drivers in table.
Change your Driver model to look as below,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Driver = new Schema({
_id: {
type:Schema.Types.ObjectId
},
name: {
type: String
},
phone: {
type: String
},
email: {
type: String
},
deleted: {
type: Boolean
},
state: {
type: Schema.Types.ObjectId, //this is the change made
Ref: 'State'
}
});
module.exports = mongoose.model('Driver', Driver);
The second step is optional. That is, in your state model,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let State = new Schema({
_id:{
type:Schema.Types.ObjectId //this is optional however
},
name: {
type: String
}
});
module.exports = mongoose.model('State', State);
That should help.

Categories