TaylorMac
TaylorMac

Reputation: 9002

Mongoose No matching document found using id() method. Error caused by asynchronous delete requests

Making asynchronous requests in a loop to delete documents from an embedded collection:

_.each deletedItem, (item) ->
     item.$delete()

Erratically throws this error:

{ message: 'No matching document found.', name: 'VersionError' }

When executing:

var resume = account.resumes.id(id);

resume.remove();

account.save(function (err, acct) {
    console.log(err);
    if(err) return next(err);
    res.send(resume);
});

After logging account.resumes and looking through the _id's of all of the resumes, the document I am attempting to find by id, exists in the collection.

530e57a7503d421eb8daca65 FIND:

{ title: 'gggff', _id: 530e57a7503d421eb8daca65 }

IN:

[{ title: 'asddas', _id: 530e57a7503d421eb8daca61 }
{ title: 'gggff', _id: 530e57a7503d421eb8daca65 }
{ title: 'ewrs', _id: 530e57a7503d421eb8daca64 }]

I assume this has to do with the fact that I am performing these requests asynchronously, or that there is a versioning issue, but I have no idea how to resolve it.

It doesn't make any sense to me how when I log the resumes, I can see the resume I attempt to find, yet if I log:

log(account.resumes.id(id));

I get undefined.

UPDATE

I've discovered that my issue is with versioning.

http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html

But I am still unsure how to resolve it without disabling versioning, which I don't want to do.

Upvotes: 3

Views: 6001

Answers (2)

Carlos Ruiz
Carlos Ruiz

Reputation: 81

MongooseJs API docs explicitly warn on disabling versioning, and recommend against it. Your issue is due to workflow. If you're updating your collection from the UI, sending the API request and not refreshing your object with the object from the backend -- then attempt to update it again, you'll encounter the error you are reporting. I suggest either consuming/updating the object scope from the API response, then __v is correctly incremented. Or don't send the __v field on the PUT API request, this way it won't conflict with version on the collection in the database.

Another option is -- when requesting the object from the backend, have the API response not send the __v field, this way you don't have to code logic to NOT send it from the frontend. On all your gets for that collection, do either one of the following (depends how you write your queries):

var model = require('model');
var qry = model.find();
qry.select('-__v');
qry.exec(function(err,results){
    if(err) res.status(500).send(err);
    if(results) res.status(200).json(results);
});

OR

var model = require('model');
model.find({}, '-__v', function(err,results){
    if(err) res.status(500).send(err);
    if(results) res.status(200).json(results);
});

Upvotes: 0

Enki
Enki

Reputation: 1705

In mongodb version 3, documents now have an increment() method which manually forces incrementation of the document version. This is also used internally whenever an operation on an array potentially alters array element position. These operations are:

$pull $pullAll $pop $set of an entire array

changing the version key

The version key is customizable by passing the versionKey option to the Schema constructor:

new Schema({ .. }, { versionKey: 'myVersionKey' });

Or by setting the option directly:

schema.set('versionKey', 'myVersionKey');

disabling

If you don’t want to use versioning in your schema you can disable it by passing false for the versionKey option.

schema.set('versionKey', false);

Upvotes: 4

Related Questions