How to save element into collection with out defining in schema - node.js

I am trying to add an element into schema object in a middleware pre save method, I defined the config as strict: false. So expecting this new element to be added and saved to the object. Below is my code which I am working on.
var mongoose = require('mongoose');
var connection = mongoose.connect('mongodb://localhost/my_database');
var Schema = mongoose.Schema
var User = new Schema({
author : String
, type : String
}, { strict: false });
var MyUserModel = mongoose.model('User', User); //create and access the model User
var u = new MyUserModel({author:'mark',type:'novel'});
u.pre('save', function(next, req){
var self = this;
self.view = 'ALL';
console.log("pre save");
next();
});
u.save(function(err){
if (err) console.log(err);
});
The problem is unable to save the new element(view) into the collection.

You need to use set:
self.set('view', 'ALL');
For properties that aren't in the schema, Mongoose cannot create a setter (whereas for properties that are in the schema, it does, and so self.author = '...' would work), so you have to set it explicitly.

Related

mongoose query doesn't return the actual object

I have added a method to my mongoose scheme. When I create an instance, I can call that object but when I query for that object and try to call the same method, it returns exception.
User.js file:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String
surname: String
});
userSchema.methods.print = function() {
console.log(this.name, this.surname);
};
module.exports = mongoose.model('User', userSchema);
The following code works as expected:
const user = new User({});
user.print();
But when I query mongodb and try to call print on the method it returns exception:
User.findById(id, function(err,user){
// print is not a function
user.print();
});
I can't see where I'm making mistake,
And suggestions ?
Thanks.
It is because you haven't created an object of User.
Change module.exports = mongoose.model('User', userSchema); to let User = module.exports = mongoose.model('User', userSchema); in the User.js file and create an object of User before calling the print method, like:
let User = require('<path>/User.js'); where you need to update path with the actual path of the file.

Dynamic schema keys in Mongoose

I have a simple requirement to get dynamic keys and their values to insert in mongo.
something like this:
[
{"key1": "val1"},
{"key2": "val2"}
]
For this I have created schema as :
As I read about [Schema.Types.Mixed],but it only makes datatype of assigned values dynamic ,not the key in my case.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var myschema = new Schema({ key: [Schema.Types.Mixed] });
module.exports = mongoose.model('DataCollection', myschema);
Can anybody point , whtat is it that I am missing.
This is my output,which shows blank value.
Thanks in advance.
I don't think it is possible to literally have a dynamic key as that defeats the purpose of a schema, but you could do something like this:
var KeyValueSchema = new Schema({
key : String,
value : String
});
module.exports = mongoose.model('KeyValueCollection', KeyValueSchema);
Alternatively using the Mixed data type you could store an entire JSON object. For example using this schema:
var mySchema = new Schema({
data : Schema.Types.Mixed
});
module.exports = mongoose.model('DataCollection', mySchema);
You could insert like:
.post(function(req, res) {
var collection = new DataCollection();
collection.data = {'key' : 'value'};
collection.save(function(err) {
if(err) res.send(err);
res.json({message:'Data saved to collection.'});
});
});

Hook to a specific Mongoose model query

I have self contained model in invoice.js
'use strict';
// load the things we need
var mongoose = require('mongoose');
var auth_filter = require('../../auth/acl/lib/queryhook');
var invoice_db = mongoose.createConnection(config.mongo.url + '/invoiceDB');
// PROMISE LIBRARY USED FOR ASYNC FLOW
var promise = require("bluebird");
var Schema = mongoose.Schema, ObjectId = Schema.Types.ObjectId;
// define the schema for our invoice details model
var invoicedetailSchema = new Schema({
//SCHEMA INFO
});
var InvoiceModel = invoice_db.model('InvoiceDetail', invoicedetailSchema);
// create the model for seller and expose it to our app
auth_filter.registerHooks(InvoiceModel);
module.exports = InvoiceModel;
I want to hook to the pre query for this model. I am trying to accomplish that using hooks but i am not successful with that. I am registering the hook using auth_filter file as below
'use strict';
var hooks = require('hooks'),
_ = require('lodash');
exports.registerHooks = function (model) {
model.pre('find', function(next,query) {
console.log('test find');
next();
});
model.pre('query', function(next,query) {
console.log('test query');
next();
});
};
What am I doing wrong? I want to keep the hooks separate so that I can call for a lot of different models.
Query hooks need to be defined on the schema, not the model. Also, there is no 'query' hook, and the query object is passed to the hook callback as this instead of as a parameter.
So change registerHooks to be:
exports.registerHooks = function (schema) {
schema.pre('find', function(next) {
var query = this;
console.log('test find');
next();
});
};
And then call it with the schema before creating your model:
var invoicedetailSchema = new Schema({
//SCHEMA INFO
});
auth_filter.registerHooks(invoicedetailSchema);
var InvoiceModel = invoice_db.model('InvoiceDetail', invoicedetailSchema);

Express, Mongoose : OverwriteModelError : Cannot Overwrite 'xxxxx' model once compiled

I'm encoutering an error when using a Mongoose Model in my program.
I've did that in the beginning of my code :
var Schema = mongoose.Schema;
mongoose.connect('xxxxx');
I used a first schema called userSchema to connect/sign up a user.
I've this code, which should do a random on the field Bonus of my DB. But when I go to the randTest page, I have this error. How can I fix it ?
app.get('/randTest', function(req,res)
{
var bonusSchema = new Schema({
bonus : [String]
});
var bonusModel = mongoose.model('Plateau', bonusSchema);
var query = bonusModel.find(null);
query.exec(function (err, allBonus){
if(err) { throw err;}
var rand = Math.floor((Math.random() *allBonus.length));
var result = allBonus[rand-1];
});
res.render('randTest', {result: result});
});
In my Jade file I've just :
extends layout
block content
script.
alert({#result});
Move the bonusModel definition outside of app.get so that it's only called once:
var bonusSchema = new Schema({
bonus : [String]
});
var bonusModel = mongoose.model('Plateau', bonusSchema);
app.get('/randTest', function(req,res)
{
var query = bonusModel.find(null);
...
});

What are Mongoose (Nodejs) pluralization rules?

I am a newbie to the Node.js, Mongoose and Expressjs. I have tried to create a table "feedbackdata" using the Mongoose in MongoDB via the following code. But it is created as "feedbackdata*s*". By Googling, I found that the Mongoose uses pluralization rules. Anyone please help me to remove the pluralization rules? or how my code should be for the "feedbackdata" table?
Below is my code:
app.post("/save",function(req,res){
mongoose.connect('mongodb://localhost/profiledb');
mongoose.connection.on("open", function(){
console.log("mongo connected \n");
});
// defining schemar variables
Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
// define schema for the feedbackdata table
var feedback_schema = new Schema({
_id: String,
url:String,
username:String,
email:String,
subscribe:String,
types:String,
created_date: { type: Date, default: Date.now },
comments: String
});
// accessing feeback model object
var feedback_table = mongoose.model('feedbackdata', feedback_schema);
var tableObj = new feedback_table();
var URL = req.param('url');
var name = req.param('name');
var email = req.param('email');
var subscribe = req.param('subscribe');
var choices = req.param('choices');
var html = req.param('html');
var receipt = req.param('receipt');
var feedbackcontent = req.param('feedbackcontent');
tableObj._id = 3;
tableObj.url = URL;
tableObj.username = name;
tableObj.email = email;
tableObj.subscribe = subscribe;
tableObj.types = choices;
tableObj.comments = feedbackcontent;
tableObj.save(function (err){
if(err) { throw err; }else{
console.log("Saved!");
}
mongoose.disconnect();
})
res.write("<div style='text-align:center;color:green;font-weight:bold;'>The above values saved successfully! <br><a href='/start'>Go back to feedback form</a></div>");
res.end();
});
The pluralization rules are in this file: https://github.com/LearnBoost/mongoose/blob/master/lib/utils.js
You can add your schema name to the 'uncountables' list, then mongoose will not pluralize your schema name.
Provide the name for the collection in options while creating schema object, then Mongoose will not do pluralize your schema name.
e.g.
var schemaObj = new mongoose.Schema(
{
fields:Schema.Type
}, { collection: 'collection_name'});
For more Info: http://mongoosejs.com/docs/guide.html#collection
The pluralization rules is here to ensure a specific naming convention.
The collection name should be plural, all lowercase and without spacing.
What are naming conventions for MongoDB?
I think you should ask yourself if you want to follow the main rule (ensured by mongoose as a default behavior) or get rid of it.
What are the perks ? What are the good points ?
You design first what is an user (User model) and then you store users into a collection. It totally make sense.
Your call.
If you ask yourself how to get the final name of the collection after the pluralization :
const newName = mongoose.pluralize()('User');

Resources