mongoose-simpledb icon indicating copy to clipboard operation
mongoose-simpledb copied to clipboard

Calling update(...) on a collection/model not working

Open mathiasm74 opened this issue 9 years ago • 6 comments

I have a user.js schema file that result in a db.User model. Now I want to remove a field called 'email_verified' from all User documents, like this:

  db.User.update(
    { email_verified: { $exists: true } },  // Query
    { $unset: { email_verified: true  } },  // Update
    { multi: true }                         // Options
  );

But this does nothing. No change. Calling this in the mongo console result in an error, becuase the collection is really called 'users'. calling db.users.update(...) in the console works fine, but result in an error when called from my node.js code (as expected).

So is simpledb preventing the db.User.update(...) call in my node code from working?

mathiasm74 avatar Nov 19 '14 14:11 mathiasm74

All simpledb does is parse your model files and then stuff them into mongoose the way mongoose likes them done. I just didn't like the way that mongoose makes you create schemas and then register them as models and blah blah blah. I found myself constantly building little auto-loader scripts similar to what simpledb offers. Eventually I realized what I was doing over and over could be a simple wrapper module, thus simpledb was born.

With that in mind, once your models are loaded onto the db object simpledb's job is done. Any calls you make to db.SomeModel... are now treading into mongoose territory, not simpledb. The User property on db is literally the mongoose model object that you'd get back if you were registering that model manually with mongoose yourself.

So I don't think this is a simpledb issue, but I'd be happy to help troubleshoot. I will try to run a similar query on a test database when I can and I'll update here with any new information.

catdadcode avatar Nov 19 '14 21:11 catdadcode

Any help appreciated!

Maybe the problem is that db.User refers to the model, and I need to make the call on the collection? If so, can I access the collection for the db.User model?

mathiasm74 avatar Nov 24 '14 20:11 mathiasm74

Yes, progress!

calling db.User.collection.update(myquery, myupdate, function(err, numAffected) {}) seems to work!

mathiasm74 avatar Nov 24 '14 20:11 mathiasm74

Would be very helpful if your documentation mentioned collections, how they're not the same as Models and how to make calls on them...

mathiasm74 avatar Nov 24 '14 20:11 mathiasm74

Again, anything after the db. is not my library, it's mongoose itself. The collection property is something mongoose has added to your User mongoose model. My documentation isn't going to duplicate the mongoose documentation but I can at least add a link to their documentation in my README.

This is literally all simpledb really does:

// myModels/User.js

// Declare a simple node module that exports a schema property.
exports.schema = {
  username: String,
  joinDate: { type: Date, default: Date.now() }
};
// app.js

var fs = require('fs');
var path = require('path');
var mongoose = require('mongoose');

// Create db object.
var db = {};

// Open a mongoose connection and store the connection object on our new db object.
db.connection = mongoose.createConnection(mongooseConnectionString);

// When the open event fires, run the following logic.
db.connection.once('open', function () {
  // Read all files from the myModels directory.
  fs.readdir('myModels', function (err, files) {
    if (err) return console.error(err);
    // Iterate over all files in the myModels directory and load all the schemas into
    // mongoose.
    files.forEach(function (file) {
      // Use the file name as the model name.
      var modelName = path.basename(file.replace(path.extname(file), ''));
      // Require the node module so we can get reference to the schema property.
      var modelData = require(path.join('myModels', file));
      // Create the mongoose schema using the schema data from the loaded module.
      var schema = new mongoose.Schema(modelData.schema);
      // Create a camel-cased version of our model name and use that as the property
      // name on our db object.
      var dbPropertyName = modelName.charAt(0).toUpperCase() + modelName.slice(1);
      db[dbPropertyName] = db.connection.model(modelName, schema);
    });
  });
});

I just wrote the above code in so many projects that I ended up turning it into this simpledb module. There is a little more to it than that because simpledb lets you define virtuals, methods, etc. in addition to schema. But for the most part the above code is all simpledb really does. The db object simpledb gives you access to is really just a simple dictionary containing all of your created mongoose models. The model properties attached to db are generated by mongoose itself, not by simpledb :)

catdadcode avatar Nov 24 '14 21:11 catdadcode

PS - I believe the collection property you are accessing is actually the underlying collection from the original mongodb driver that Mongoose uses under the hood. I believe your original code using just the Mongoose model should have worked, but I still haven't ran a test yet. I'll try to do it sometime today.

catdadcode avatar Nov 24 '14 21:11 catdadcode