0

I have a structure like this:

{
  ...
  _id: <projectId>
  en-GB: [{
    _id: <entryId>,
    key: 'some key',
    value: 'some value',
  }]
}

And I've tried updating it with Mongoose (and raw mongodb too) like this:

const result = await Project
  .update({
    _id: projectId,
    'en-GB._id': entryId,
  }, {
    $set: {
      'en-GB.$.key': 'g000gle!!',
    },
  })
  .exec();

I've checked that the IDs are correct. But it doesn't update anything:

{ n: 0, nModified: 0, ok: 1 }

What am I doing wrong? Thanks

6
  • It seems to me that it's failing to match any of the documents (note the n: 0). I see nothing wrong with your query itself, so I would recommend ensuring that the ids both on the document and in your query are of the correct type (e.g. make sure you're not comparing strings to ObjectIds). I would also recommend attempting a simple find on your fields individually and then together to help isolate the problem. Commented Jan 10, 2018 at 20:34
  • thanks, I am passing in IDs as strings, I wonder if I have to wrap them in ObjectId's. I'll double check the IDs are correct but I think they are Commented Jan 10, 2018 at 20:37
  • Yes, they absolutely must be ObjectIds. There are some methods like findByIdAndUpdate which take an id string, but methods that don't explicitly operate on ids typically expect your id strings to be wrapped within an ObjectId. Commented Jan 10, 2018 at 20:40
  • Additionally, methods like findByIdAndUpdate only take an id string as one parameter. When you're associating an id with a document field (e.g. {$set: {key: some_id}}), you must always, always use an ObjectId. This is true for every part of a query, from the match to the update. String representations of ids are a very special case and should always be treated as the exception to the rule. Commented Jan 10, 2018 at 20:42
  • YES! Thanks that worked!! With mongoose String seems to work on _id, but failed on 'en-GB._id'. Feel free to add it as an answer Commented Jan 10, 2018 at 20:49

1 Answer 1

1

As discussed in the comments on the question, the issue is directly related to passing in a string representation of an id in the query as opposed to using an ObjectId. In general, it's good practice to treat the use of ObjectIds as the rule and the use of string representations as special exceptions (e.g. in methods like findByIdAndUpdate) in order to avoid this issue.

const { ObjectId } = require('mongodb');

.update({
  _id: ObjectId(projectId),
  'en-GB._id': ObjectId(entryId),
})
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.