I need to change the collection based on model data in mongoose. I am tapping into the pre save event:
mySchema.pre('save', function (next) {
this.schema.set('collection', getCollectionName(this.dt));
next();
});
But that seems to have no effect on the save destination. Those collections seemed to be set in the mongoose model already. Any ideas on where I might be able to set this after the model has been created?
Related
I have an array models with all the model names in my project. I get any of the model name in request.params.model. I also get some data in request.body. Now all I wanted to do is insert the data received into the collection pointed by request.params.model. How can I achieve this?
I used model method of mongoose to achieve this. Below is a sample mongoose query.
require("mongoose").model(req.params.model).create(req.body, function(err, doc) {
res.json(doc);
});
I am using the Waterline ORM to interface with my database.
I am extend Waterline.Collections into a new objects and assign them to a module:
var Waterline = require('waterline');
var User = Waterline.Collection.extend({
...some fields...
attributes:{
col_a:{
type:'integer'
},
touch_user:function(){
// increment col_a and update in table
}
}
});
export = module.exports = User;
I query for the specific models I need to update, then manipulate them in a promise.
database.models.users.findAll().where({'id':1}).then(...model manipulation...)
There is a task I perform often, almost whenever I access the model. I would like to encapsulate this task in a function associated with the instance so I can simple call "touch_user" and the relevant fields will be updated for the model i call it on.
I am not able to access the Waterline query methods (such as .update()) from the model instance after a model is queried like so:
database.models.users.findAll().where({'id':1).then((user)=>{
user.touch_user();
//user.update // does not work
});
But it is not until I query it that I retrieve the data associated with the record.
I would like user.touch_user() to increment col_a in the users table similar to the following
database.models.users.findAll().where({'id':1).then((user)=>{
user.touch_user();
database.models.users.update(user.id, {'col_a':user.col_a+1});
});
The problem with the above is that the user object does not accurately reflect the update to the table.
What I ended up doing was creating a class method to update the model and the instance. Not exactly what I want, but it does in a pinch to keep the model and table synced
var User = Waterline.Collection.extend({
...some fields...
attributes:{
col_a:{
type:'integer'
},
},
// touch_user is a class method here
touch_user:function(user){
// update model instance
user.col_a += 1;
// update database table
database.models.users.update(user.id, {'col_a':user.col_a).exec(function(){});
}
});
Called like so
database.models.users.findAll().where({'id':1).then((user)=>{
...modify user...
database.models.users.touch_user(user);
...other changes to user that have to occur here...
database.models.users.touch_user(user);
});
In mongoose, I need to find a maximal property value of given model. I have tried dynamically created the mongoose model in a function as
var DynamicSchema=new Schema({id:Number},{collection:collection});
var DynamicModel=mongoose.model('DynamicModel',DynamicSchema);
but after second run of the function I get an error 'OverwriteModelError: Cannot overwrite DynamicModel model once compiled.'
So I tried to create a model in intitialization without setting the collection as
var DynamicSchema = new Schema({id:Number});
var DynamicModel=mongoose.model('DynamicModel',DynamicSchema);
and in a function, tried to set the property collection by
var DynamicModel=mongoose.model('DynamicModel');
DynamicModel.set({collection : collection});
But it does not work. Is there any solution for this situation?
Learning in progress - Stuck working out how have to have 2 separate documents in different collections: events & event reviews
I'm able to reference objectId's between the two but what's the best way to reference data from within those documents if I wanted to populate information from the event into the event review as it's created? I've been trying to trying to google the answer for a few hours now but have so far been unsuccessful with each method I've found. Not looking for a specific answer just somebody with a bit more knowledge to point me in the right direction.
You need to explicitly state that a field in your event reviews schema references the ObjectID of a document in your event collection. Like so...
var mongoose = require('mongoose'), Schema = mongoose.Schema
var EventReviewSchema = new Schema({
someField:{
type: Schema.Types.ObjectId,
ref: 'Event' // Note this is the name of the event model, not schema
}
})
You mentioned that you want to do this "as it's created."
Remember that in MongoDB, write operations are only atomic at the single document level. So there is no "built in" way to guarantee that every event document you create will have a corresponding event review document (I assume that this is what you're trying to do.)
You will need to save an event document, grab that document's ObjectId and use it to populate the appropriate field in your event review document. But remember, there is chance that the second write operation will fail if some error occurs between the time of the first and second write operation.
My advice is to try to write your application in a way that can use a mongoose FindOrCreate method (with a plugin) when querying for event review documents. It's a quick and dirty way to solve this problem.
EDIT:
var Review = mongoose.model('Review', EventReviewSchema)
module.exports.reviewCreate = function(req, res, next) {
var eventid = req.params.eventid
if (eventid) {
var review = new Review() // Review model
review.someField = eventId
review.save(function(err){
if(err) return next(err)
// save successful
})
}
}
Using mongoose on node.js:
Can I access the _id field on a model before it has been saved to the database and be sure that the ID will not change?
For example, I would like to do the following:
var model = new mongoose.model('MyModel');
someOtherObject.myModelId = String(model._id);
// Some more code...
model.save(...);
In Mongoose, _id values must always be assigned client-side as the docs indicate that:
Mongoose forces the db option forceServerObjectId false and cannot be overridden.
So the model._id value you get in the first line of your code will not be changed unless you do it in your own code before calling model.save.