var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = mongoose.model('Cat', { name: String });
var kitty = new Cat({ name: 'Zildjian' });
console.log(kitty);
kitty.save();
console.log(kitty);
this output:
{ name: 'Zildjian', _id: 523194d562b0455801000001 } twice
I've tried by delaying the save after a timeout, but it's the same, which points to the _id being set on the new Cat and not the .save()
Is this because of mongodb or mongoose, why is the _id set before the actual persistence?
Most MongoDb drivers will automatically generate the ObjectId/_id client side, including the native driver for Node.js. There's a tiny amount of locking that occurs to generate an ID uniquely, so there's little reason to not distribute the generation to connected clients.
Mongoose needs a unique identifier to track and reference objects, so it creates an identifier immediately.
In the Node.JS client you can optionally set for example the property forceServerObjectId to true to control this behavior.
However, this cannot be overridden when using Mongoose per the docs:
Mongoose forces the db option forceServerObjectId false and cannot be
overridden. Mongoose defaults the server auto_reconnect options to
true which can be overridden. See the node-mongodb-native driver
instance for options that it understands.
Related
In previous versions of Mongoose (for node.js) there was an option to use it without defining a schema
var collection = mongoose.noSchema(db, "User");
But in the current version the "noSchema" function has been removed. My schemas are likely to change often and really don't fit in with a defined schema so is there a new way to use schema-less models in mongoose?
I think this is what are you looking for Mongoose Strict
option: strict
The strict option, (enabled by default), ensures that values added to our model instance that were not specified in our schema do not get saved to the db.
Note: Do not set to false unless you have good reason.
var thingSchema = new Schema({..}, { strict: false });
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing({ iAmNotInTheSchema: true });
thing.save() // iAmNotInTheSchema is now saved to the db!!
Actually "Mixed" (Schema.Types.Mixed) mode appears to do exactly that in Mongoose...
it accepts a schema-less, freeform JS object - so whatever you can throw at it. It seems you have to trigger saves on that object manually afterwards, but it seems like a fair tradeoff.
Mixed
An "anything goes" SchemaType, its flexibility comes at a trade-off of
it being harder to maintain. Mixed is available either through
Schema.Types.Mixed or by passing an empty object literal. The
following are equivalent:
var Any = new Schema({ any: {} });
var Any = new Schema({ any: Schema.Types.Mixed });
Since it is a schema-less type, you can change the value to anything
else you like, but Mongoose loses the ability to auto detect and save
those changes. To "tell" Mongoose that the value of a Mixed type has
changed, call the .markModified(path) method of the document passing
the path to the Mixed type you just changed.
person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
Mongoose Schema Types
Hey Chris, take a look at Mongous. I was having the same issue with mongoose, as my Schemas change extremely frequently right now in development. Mongous allowed me to have the simplicity of Mongoose, while being able to loosely define and change my 'schemas'. I chose to simply build out standard JavaScript objects and store them in the database like so
function User(user){
this.name = user.name
, this.age = user.age
}
app.post('save/user', function(req,res,next){
var u = new User(req.body)
db('mydb.users').save(u)
res.send(200)
// that's it! You've saved a user
});
Far more simple than Mongoose, although I do believe you miss out on some cool middleware stuff like "pre". I didn't need any of that though. Hope this helps!!!
Here is the details description: [https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html][1]
const express = require('express')()
const mongoose = require('mongoose')
const bodyParser = require('body-parser')
const Schema = mongoose.Schema
express.post('/', async (req, res) => {
// strict false will allow you to save document which is coming from the req.body
const testCollectionSchema = new Schema({}, { strict: false })
const TestCollection = mongoose.model('test_collection', testCollectionSchema)
let body = req.body
const testCollectionData = new TestCollection(body)
await testCollectionData.save()
return res.send({
"msg": "Data Saved Successfully"
})
})
[1]: https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html
Note: The { strict: false } parameter will work for both create and update.
Its not possible anymore.
You can use Mongoose with the collections that have schema and the node driver or another mongo module for those schemaless ones.
https://groups.google.com/forum/#!msg/mongoose-orm/Bj9KTjI0NAQ/qSojYmoDwDYJ
In previous versions of Mongoose (for node.js) there was an option to use it without defining a schema
var collection = mongoose.noSchema(db, "User");
But in the current version the "noSchema" function has been removed. My schemas are likely to change often and really don't fit in with a defined schema so is there a new way to use schema-less models in mongoose?
I think this is what are you looking for Mongoose Strict
option: strict
The strict option, (enabled by default), ensures that values added to our model instance that were not specified in our schema do not get saved to the db.
Note: Do not set to false unless you have good reason.
var thingSchema = new Schema({..}, { strict: false });
var Thing = mongoose.model('Thing', thingSchema);
var thing = new Thing({ iAmNotInTheSchema: true });
thing.save() // iAmNotInTheSchema is now saved to the db!!
Actually "Mixed" (Schema.Types.Mixed) mode appears to do exactly that in Mongoose...
it accepts a schema-less, freeform JS object - so whatever you can throw at it. It seems you have to trigger saves on that object manually afterwards, but it seems like a fair tradeoff.
Mixed
An "anything goes" SchemaType, its flexibility comes at a trade-off of
it being harder to maintain. Mixed is available either through
Schema.Types.Mixed or by passing an empty object literal. The
following are equivalent:
var Any = new Schema({ any: {} });
var Any = new Schema({ any: Schema.Types.Mixed });
Since it is a schema-less type, you can change the value to anything
else you like, but Mongoose loses the ability to auto detect and save
those changes. To "tell" Mongoose that the value of a Mixed type has
changed, call the .markModified(path) method of the document passing
the path to the Mixed type you just changed.
person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved
Mongoose Schema Types
Hey Chris, take a look at Mongous. I was having the same issue with mongoose, as my Schemas change extremely frequently right now in development. Mongous allowed me to have the simplicity of Mongoose, while being able to loosely define and change my 'schemas'. I chose to simply build out standard JavaScript objects and store them in the database like so
function User(user){
this.name = user.name
, this.age = user.age
}
app.post('save/user', function(req,res,next){
var u = new User(req.body)
db('mydb.users').save(u)
res.send(200)
// that's it! You've saved a user
});
Far more simple than Mongoose, although I do believe you miss out on some cool middleware stuff like "pre". I didn't need any of that though. Hope this helps!!!
Here is the details description: [https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html][1]
const express = require('express')()
const mongoose = require('mongoose')
const bodyParser = require('body-parser')
const Schema = mongoose.Schema
express.post('/', async (req, res) => {
// strict false will allow you to save document which is coming from the req.body
const testCollectionSchema = new Schema({}, { strict: false })
const TestCollection = mongoose.model('test_collection', testCollectionSchema)
let body = req.body
const testCollectionData = new TestCollection(body)
await testCollectionData.save()
return res.send({
"msg": "Data Saved Successfully"
})
})
[1]: https://www.meanstack.site/2020/01/save-data-to-mongodb-without-defining.html
Note: The { strict: false } parameter will work for both create and update.
Its not possible anymore.
You can use Mongoose with the collections that have schema and the node driver or another mongo module for those schemaless ones.
https://groups.google.com/forum/#!msg/mongoose-orm/Bj9KTjI0NAQ/qSojYmoDwDYJ
I have a have several mongo databases for separate parts of a website I am making. One of those databases is for sessions. I am using Connect Mongo to store the sessions in the databases. I can't seem to store in to session a ObjectId that references a model I made for a user. But when I read the session I just get the ObjectId I stored and not the object. I already changed stringify to false.
Is it possible to do this with Connect Mongo?
I already tried making a schema and store that schema to a session variable to see if it will give back the user object I have referenced to. I included this code below.
var mongoose = require('mongoose');
var DBsessions = require('../../setup/DBconnect.js').DBsessions;
var QuickChatRefScheme = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = DBsessions.model('QuickChatRef', QuickChatRefScheme);
And to use this I have:
request.session.allowedChatUser = new QuickChatRef({user:new mongoose.Types.ObjectId(toUser._id)});
Where toUser._id is provided and is a already existing user _id field.
I need the session to ref the user so when node queries the session from the db the user object gets pulled back too.
I've just started with mongoose. I have a creation script with mongoose that creates the schemas and db with sample data.
Now I write the actual application. Do I need to create the schema object each time my application runs, or is it already available somehow?
In other words do I need to run this code in every app that uses mongoose to access the db or just the first time:
var Comments = new Schema({
title : String
, body : String
, date : Date
});
How would the answer change if I have setters/validations/etc?
One defines Schema so application understands how to map data from the MongoDB into JavaScript objects. Schema is a part of application. It has nothing to do with database. It only maps database into JavaScript objects. So yes - if you want to have nice mapping you need to run this code in every application that needs it. It also applies to getters/setters/validations/etc.
Note however that doing this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema; // <-- EDIT: missing in the original post
var Comments = new Schema({
title : String
, body : String
, date : Date
});
mongoose.model("Comments", Comments);
will register Schema globaly. This means that if the application you are running is using some exterior module, then in this module you can simply use
var mongoose = require('mongoose');
var Comments = mongoose.model("Comments");
Comments.find(function(err, comments) {
// some code here
});
(note that you actually need to register the Schema before using this code, otherwise an exception will be thrown).
However all of this works only inside one node session, so if you are running another node app which needs the access to the Schema, then you need to call the registration code. So it is a good idea to define all Schemas in separate files, for example comments.js may look like this
var mongoose = require('mongoose');
var Schema = mongoose.Schema; // <-- EDIT: missing in the original post
module.exports = function() {
var Comments = new Schema({
title : String
, body : String
, date : Date
});
mongoose.model("Comments", Comments);
};
then create file models.js which may look like this
var models = ['comments.js', 'someothermodel.js', ...];
exports.initialize = function() {
var l = models.length;
for (var i = 0; i < l; i++) {
require(models[i])();
}
};
Now calling require('models.js').initialize(); will initialize all of your Schemas for a given node session.
You do need to run this initialization code every time you run your app to register your app's Schemas with mongoose.
When your app ends, mongoose does not store your Schema(s). So, the next time you run an app that uses a Schema, you need to register your Schema(s) again.
However, it's fairly easy to set up your app to do so.
Here are two links to code that demonstrates how one can initialize schemas in mongoose. The first is in JavaScript, the second is in CoffeeScript.
https://github.com/fbeshears/register_models
https://github.com/fbeshears/register_coffee_models
The JavaScript demos is just one app.
The CoffeeScript code has two separate apps. The first stores documents with MongoDB, the second finds and displays the documents stored by the first app.
I'm using Mongoosejs, with MongoDB and Node.js.
I followed some online tutorials and created myself a test app as below, but keep getting the error message "propert model of object mongoose is not a function.
I dont understand what this means and why its erroring since i followed the online tutorials near enough the same.
Here is my code
// MongoDB test app. Getting to know MongoDB via MongooseJS
var mongoose = require ('mongoose'),
Schema = mongoose.Schema;
//Create Schema
var Storydb = new Schema ({
title: String,
body: String,
date: Date
});
mongoose.connect('mongodb://localhost/test');
//setup model and pass it schema
mongoose.model = ('Storydb',Storydb);
var StoryModel = mongoose.model ('Storydb');
var story = new StoryModel();
//Insert Data
story.title = 'The Man in the green shirt';
story.body = 'once upon a time, way back';
story.date = Date.now();
//save
story.save(function(err){
if (err) {throw err; }
console.log('saved story');
mongoose.disconnect();
});`
I've already tested my MongoDB connection. No issues there, and i am able to insert and retrieve data via the Mongo CLI.
I have also tested my Node.js configuration with basic Hello World examples, and no issues with configuration.
Instead of:
//setup model and pass it schema
mongoose.model = ('Storydb',Storydb);
you should do:
//setup model and pass it schema
mongoose.model('Storydb',Storydb);