save() not working with statics in mongoose - node.js

Below are various methods i tried to save documents but did not work. what am i doing wrong? Is it the correct way to use static? Is method needed here? If yes how will it be implemented in this situation?
Method 1:
userSchema.statics.saveUser = function(data, callback){
data.save(callback);
};
Result - save is not a function
Method 2:
userSchema.statics.saveUser = function(data, callback){
data = new userSchema(data);
data.save(callback);
};
Result - userSchema is not a function
Method 3:
userSchema.statics.saveUser = function(data, callback){
var user = new user(data);
data.save(callback);
};
var user = Mongoose.model('user', userSchema);
Result - user is not a function
Edit
Even the below methods does not seem to be working
Method 4:
userSchema.statics.saveUser = function(data, callback){
var user = new this(data);
user.save(callback);
};
Method 5: JohnnyHK suggested way
userSchema.statics.saveUser = function(data, callback){
var user = new this();
user.data = data;
user.save(callback);
};
userSchema is like this
var db = require('../database');
var Mongoose = db.Mongoose;
require('mongoose-long')(Mongoose);
var SchemaTypes = Mongoose.Schema.Types;
var userSchema = new Mongoose.Schema({
_id:{ type: String, required: true, unique:true },
// many fields with type as string and number
.
.
.
Number:{ type: SchemaTypes.Long, min: 0, default: 0},
});
// query functions here
var user = Mongoose.model('user', userSchema);
// exporting model here
Everything works fine if use this.create(data, callback); instead of save but i want to use save for some reasons.
Data before using it for save
[ { _id: '2A864493-52614B19',
name: 'xyz',
date: 'some date',
...
...
...
city: 'adf'
} ]

You need to create an instance of your model, because the save method is only available for instance.
var User = mongoose.model('user', UserSchema);
UserSchema.statics.saveUser = function(data, callback){
var user = new this(data);
user.save(callback);
};
And please, avoid duplication of variables with adding some uppercase. It's more readable and less hazardous.
Mongoose documentation : http://mongoosejs.com/docs/models.html

Related

How to implement more than one collection in get() function?

My model university.js
const mongoose = require('mongoose');
const UniversitySchema = mongoose.Schema({
worldranking:String,
countryranking:String,
universityname:String,
bachelorprogram:String,
masterprogram:String,
phdprogram:String,
country:String
},{collection:'us'});
const University =module.exports = mongoose.model('University',UniversitySchema);
My route.js
const express = require('express');
const router = express.Router();
const University = require('../models/university');
//retrieving data
//router.get('/universities',(req,res,next)=>{
// University.find(function(err,universities){
// if(err)
// {
// res.json(err);
//}
// res.json(universities);
//});
//});
router.get('/usa',function(req,res,next){
University.find()
.then(function(doc){
res.json({universities:doc});
});
});
module.exports= router;
How to implement multiple collections in this get() function? I put my collection name in the model. Please help me with a solution to call multiple collections in get() function.
Here is Example to use multiple collection names for one schema:
const coordinateSchema = new Schema({
lat: String,
longt: String,
name: String
}, {collection: 'WeatherCollection'});
const windSchema = new Schema({
windGust: String,
windDirection: String,
windSpeed: String
}, {collection: 'WeatherCollection'});
//Then define discriminator field for schemas:
const baseOptions = {
discriminatorKey: '__type',
collection: 'WeatherCollection'
};
//Define base model, then define other model objects based on this model:
const Base = mongoose.model('Base', new Schema({}, baseOptions));
const CoordinateModel = Base.discriminator('CoordinateModel', coordinateSchema);
const WindModel = Base.discriminator('WindModel', windSchema);
//Query normally and you get result of specific schema you are querying:
mongoose.model('CoordinateModel').find({}).then((a)=>console.log(a));
In Short,
In mongoose you can do something like this:
var users = mongoose.model('User', loginUserSchema, 'users');
var registerUser = mongoose.model('Registered', registerUserSchema, 'users');
This two schemas will save on the 'users' collection.
For more information you can refer to the documentation: http://mongoosejs.com/docs/api.html#index_Mongoose-model or you can see the following gist it might help.
Hope this may help you. You need to modify according to your requirements.

Correct approach to mongoose schema collection property

I need to read a collection identified connected to a mongoose model. Is the correct approach to read the property model.schema.options.collection directly or is there any more suitable approach?
As far as i have understood, you want to use the property of your mongoose schema. i will provide you with a small example to how you can use it effectively.
Your model file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//Schema for User
var UserSchema = new Schema({
name: {
type: String,
},
email: {
type: String
},
password: {
type: String,
},
});
module.exports = mongoose.model('User', UserSchema);
In your function where you want to include this model
var User = require('/path/models/user');
var UserController = {
create: function(req, res){
var user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.password = req.body.password;
//rest of the functionality on these bod params.
}
}
I hope this small example will be able to help.

Mongoose saving for populate

I'm new to Mongoose and Nodejs developement in general and I've got a bit of confusion around how to properly set up saving my records. Here are my two schemas:
Download
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var downloadSchema = Schema({
title : String,
description : String,
_project : { type: Schema.Types.ObjectId, ref: 'Project' }
});
module.exports = mongoose.model('Download', downloadSchema);
Project
...
var projectSchema = Schema({
name : String,
url : String,
pwd : String,
_downloads : [{type: Schema.Types.ObjectId, ref: 'Download' }]
});
module.exports = mongoose.model('Project', projectSchema);
This appears to be working correctly. The documentation explains my use-case of saving a download and linking a project, but I'm not sure how to properly populate the Project._downloads. Here's what I've done:
Express route handler:
function createDownload(req, res) {
// the Project Id is passed in the req.body as ._project
var dldata = req.body;
Project.findOne({ _id : dldata._project }, function(err, project) {
var dload = new Download(dldata);
dload.save( function (err, download) {
project._downloads.push(download._id);
project.save( function(err){
var msg = {};
if(err) {
msg.status = 'error';
msg.text = err;
}else {
msg.status = 'success';
msg.text = 'Download created successfully!';
}
res.json(msg);
});
});
});
}
This seems overcomplicated to me. Am I supposed to be manually pushing to the ._downloads array, or is that something Mongoose is supposed to handle internally based on the schema? Is there a better way to achieve it so that I can do:
Download.find().populate('_project').exec( ...
as well as:
Project.findOne({_id : _projectId}).populate('_downloads').exec( ...
According to the mongoose docs there are 2 ways to add subdocs to the parent object:
1) by using the push() method
2) by using the create() method
So I think that your code can be a bit simplified by eliminating the operation of saving a new Download item:
function createDownload(req, res) {
var dldata = req.body;
Project.findOne({ _id : dldata._project }, function(err, project) {
// handle error
project._downloads.push(dldata);
project.save(function(err) {
// handle the result
});
});
}
or
function createDownload(req, res) {
var dldata = req.body;
Project.findOne({ _id : dldata._project }, function(err, project) {
// handle error
project._downloads.create(dldata);
project.save(function(err) {
// handle the result
});
});
}

how use Schema methods in mongoose sub-documents after loading

I have the following scheme in the mongoose
var Schema = mongoose.Schema;
var CellSchema = new Schema({
foo: Number,
});
CellSchema.methods.fooMethod= function(){
return 'hello';
};
var GameSchema = new Schema({
field: [CellSchema]
});
if create new document like:
var cell = new CellModel({foo: 2})
var game = new GameModel();
game.field.push(cell);
game.field[0].fooMethod();
it's correctly work. But if you run this code:
GameModel.findOne({}, function(err, game) {
console.log(game);
game.field[0].fooMethod()
})
i get TypeError: game.field[0].fooMethod is not a function
and console log is
{
field:
[ { foo: 2,
_id: 5675d5474a78f1b40d96226d }
]
}
how correct load sub-document with all schema methods?
You have to define the methods on the embedded schema before defining the parent schema.
Also you have to reference CellSchema instead of 'Cell'
var CellSchema = new Schema({
foo: Number,
});
CellSchema.methods.fooMethod = function() {
return 'hello';
};
var GameSchema = new Schema({
field: [CellSchema]
});

mongoose not retrieving _id

I am trying to find a document from mongo, but the findOne() brings the document with an undefined _id field.
why?
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/school');
var Schema = mongoose.Schema;
var scoreSchema = new Schema({
type: String,
score: Number
});
var studentSchema = new Schema({
name: String,
scores: [scoreSchema]
});
var mod = mongoose.model('Student', studentSchema);
mod.findOne(function(err, stud) {
console.log('id:' + stud._id);
});
You need to pass something to find in your query. For example:
mod.findOne({name: 'John'}, function(err, stud) {
console.log('id:' + stud._id);
});
See here on how to make queries in Mongoose.
You're not querying anything, notice the {} before the callback.
mod.findOne({}, function(err, stud) {
console.log('id:' + stud._id);
});
You might want to have a look at the Mongoose documentation.

Resources