I am trying to use mongoose to create a database and a collection in it. My code is:
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/testdb');
var Schema = mongoose.Schema;
var UserInfo = new Schema({
username : String,
password : String
});
mongoose.model('UserInfo', UserInfo);
var user = db.model('UserInfo');
var admin = new user();
admin.username = "sss";
admin.password = "ee";
admin.save();
When I run this code, mongoose created collection named UserInfo instead of userinfo.
How to force collection name in mongoose?
This should do it
var UserInfo = new Schema({
username : String,
password : String
}, { collection: 'userinfo' });
See this link from the Mongoose documentation for more information.
If you are using mongoose 2.0.0, pass the collectionName as the third argument
mongoose.model('UserInfo', UserInfo, 'UserInfo');
Mongoose will add 's' to collection name by default. If you want to avoid that, just pass as third argument the name of the collection:
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/testdb');
var Schema = mongoose.Schema;
var UserInfo = new Schema({
username: String,
password: String
});
mongoose.model('UserInfo', UserInfo, 'UserInfo')
tan = new user();
admin.username = 'sss';
admin.password = 'ee';
admin.save();
API structure of mongoose.model is this:
Mongoose#model(name, [schema], [collection], [skipInit])
What mongoose do is that, When no collection argument is passed, Mongoose produces a collection name by pluralizing the model name. If you don't like this behavior, either pass a collection name or set your schemas collection name option.
Example:
var schema = new Schema({ name: String }, { collection: 'actor' });
or
schema.set('collection', 'actor');
or
var collectionName = 'actor'
var M = mongoose.model('Actor', schema, collectionName);
You need to set the collection name in your schema.
new Schema({...},{collection: 'userInfo'});
Mongoose maintainer here. We recommend doing mongoose.model('UserInfo', UserInfo, 'UserInfo');, third arg to mongoose.model() is the collection name. Here's the relevant docs.
Passing a third argument on module.exports = mongoose.model('name', schema, 'collection') overrides the automatic collection name based on model name, which has already been answered.. but there are 2 other ways,
per mongoose.model doco link:
https://mongoosejs.com/docs/api.html#mongoose_Mongoose-model
there are 3 methods to manually enter a collection name:
var schema = new Schema({ name: String }, { collection: 'actor' });
// or
schema.set('collection', 'actor');
// or
var collectionName = 'actor'
var M = mongoose.model('Actor', schema, collectionName)
Answer:
mongoose.model('UserInfo', UserInfo, 'userinfo'); //3rd parameter 'userinfo': as collection name
Better explanation with syntax:
Mongoose.model(name, [schema], [collection], [skipInit])
Parameters Explanation:
1st parameter - name model name
2nd parameter [schema] schema name
3rd parameter [collection] collection name (optional, induced from model name)
4th parameter [skipInit] whether to skip initialization (defaults to false)
your model name : userInfo.js
in express route file or app.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/testdb');
then in your userInfo.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserInfo = new Schema({
username : String,
password : String
});
module.exports = mongoose.model('UserInfo', UserInfo);
Related
I'm using mongoose-double to define Double type for mongoose.
My schema contain values property is an array of Double.
In pre-save middleware, init values is an array with 6 items 1000.
Check in mongo, 1000 type is int32
const mongoose = require('mongoose');
require('mongoose-double')(mongoose);
const Double = mongoose.Schema.Types.Double;
const test = new mongoose.Schema({
values: [Double]
})
test.pre('save', function(next) {
this.values = new Array(6).fill(1000),
})
I did what wrong ?
Well, in my opinion, you don't need to use Double.
As far as I know, there is 'Number' type in mongoose schema and it can be double, number and etc.
So use Number instead of Double.
const test = new mongoose.Schema({
values:Number
})
but in your case, you should use like this.
const test = new mongoose.Schema({
values:[Number]
})
This is my Schema:
var userScheme = mongoose.Schema({
aField:String,
info: {
type:{
local: {
email:String
}
},
select:false
}
});
When I try to create a new user this works fine:
var newUser = new User()
newUser.aField="Something"
newUser.save()
But when I try to access the field that has select:false, I can't access the data. so this doesn't work:
var newUser = new User()
newUser.aField="something"
newUser.info.local.email="email#domain.com"
newUser.save()
The error I get is:
TypeError: Cannot read property 'local' of undefined
My guess is that the new Model is returned without the info field becuase it is set to select:false.
How can I make the new Model() return all the fields including those set to 'select:false'?
Thanks!
Turns out the select:false had nothing to do with it.
The culprit was the fact that info has no values by default and there for was not included in the model at all.
The solution was to create a new schema just for info, and to include it in the user schema like this:
var userScheme = mongoose.Schema({
aField:String,
info: {
type:infoSchema,
default:infoSchema, //Without this, the new document will still not include an 'info' document,
select:false
}
});
Hope this helps anyone. This was just 3 hours of my life.
I have this model setup. I want a parent record with an array of sub docs.
The sub docs have a schema, and use inheritance.
//
// Children
function abstractSchema() {
Schema.apply(this, arguments);
this.add({
name: String
});
};
util.inherits(abstractSchema, Schema);
var mySchema = new abstractSchema();
//
// Inherited Types
var textPropertySchema = new abstractSchema({
length: Number
});
var numberPropertySchema = new abstractSchema({
dp: Number
});
//
// Parent Model
var myModelSchema = mongoose.Schema({
name: String,
properties : [mySchema]
});
When i save each an instance of numberPropertySchema or textPropertySchema, the _t (type is written) and is able to deserialise properly.
When however added as a sub doc array, they're all persisted with the base object properties only.
Is there any way round this? any extensions that could be used?
Thanks
sam
I have users model that can hold multiple notifications. In the NotificationSchema the notifier holds users ID and it references the users model. When I execute the following query :
User.find().populate('notifications.notifier').exec(function(err,users){
//users[0].notifications[0].notifier
//I am getting all fields from the referenced user
//I don't want the whole document but some fields only
});
How can someone Limit / Restrict the fields that should be available while referencing to some model.
Here is the users model
var NotificationSchema =new Schema({
notifier : {type:Schema.Types.ObjectId, ref:'users'},
//How could I say :
//notifier : {type:Schema.Types.ObjectId, ref:'users', fields:['_id', 'name']}
//because I know what fields do I need from referenced model for this Schema.
__SOME__
__OTHER__
__FIELDS__
});
var UsersSchema = new Schema({
name : {given:String, middle:String, family:String}
email:String,
password:String,
notifications : [NotificationSchema]
});
var Users = mongoose.model('users', UsersSchema);
BTW, I do not have separate model for NotificationSchema.
If this feature is not available out of the box how could I implement it manually. Am I missing some docs? Please let me know the robust way of doing it.
I found it in mongoose docs
I found the answer in Field Selection Section of the documentation
User.find().populate('notifications.notifier', '_id name').exec(function(err, users) {
//users[0].notifications[0].notifier ^^^^^^^^^ HOW FUNNY
//Yes I am getting '_id' and 'name' fileds only
});
js and mongodb.I have created a model file named models like the one given below
User = new Schema({
username : String
, password : String
, created_at : Date
});
mongoose.model('User', User);
exports.defineModels = defineModels;
In app.js i have called the defineModels like this:
var models = require('./models'),
models.defineModels(mongoose, function() {
app.User = User = mongoose.model('User');
db = mongoose.connect(app.set('db-uri'));
})
I can't call save method directly on User or can I?
i want to save data in User what could be the function for the same.any answer will be appriciated
To do what you want, you should have something like this:
var user = new User({username: 'Name', password: 'unsecure'});
user.save();
There are a few things odd with your code, so I highly suggest going over a tutorial that uses express and mongoose to create a sample site (most likely you can find a blog).
Here is one I made: https://github.com/mathrawka/node-express-starter
Good luck!