0

I have my Person schema like this :

const schema = new mongoose.Schema({
    _id: Number,
    name: String,
    birthday: Date,
    sex: String
});

schema.pre('findOneAndUpdate', async function (next) {
    try {
        let counter = await Counters.findByIdAndUpdate('person',
            {
                $inc: {
                    value: 1
                }
            },
            { new: true}
        );

        this._update._id = counter.value;

        next();
    }
    catch (err) {
        next(err);
    }
});

The problem is when I try to add some new persons with findOneAndUpdate and upsert: true, it generates a CastError: Cast to ObjectId failed for value "18" at path "person".

My _id is defined as a Number so I don't understand why it's trying to cast it to an ObjectId ?

Update :

I found my problem, the Person model is referenced in some other model but I forgot to change the ref type in the other model...

person: {
    type: Number, //HERE
    ref: 'person',
    required: true
}
HRK44
  • 2,382
  • 2
  • 13
  • 30
  • 1
    Would be nice if you can provide whole code. I think the error is something from another place which is not posted here. Can you post your `upsert` code here.? – Hardik Shah Nov 12 '18 at 13:26
  • @HardikShah Indeed I found the issue, I'll update my question thanks – HRK44 Nov 12 '18 at 13:29

2 Answers2

0

You can change the type of the_id property although ins't a good approach, but actually you can't change the value since it's immutable and represents the primary key of the document. Keep in mind that _id is very important for MongoDB life cycle, like indexing. If you aim to change an Entity key, you can create other property, something like person_id.

BrTkCa
  • 4,703
  • 3
  • 24
  • 45
  • I've been searching for a lot of tutorials/guides online on how to build custom ids with mongo and this is an approach used by a lot of people - basically hooking on the ``.pre('save')`` (or in this case the ``findOneAndUpdate``) - also I don't want to change the ``_id``, I want to set it if it is not already set in case of an ``upsert`` – HRK44 Nov 12 '18 at 13:14
  • I got it. Probably the tutorials is used to generate other document (like a copy), because you won't be able to update the `_id` itself, MongoDB never won't you to do that. Think that you can create how much documents as you want, but each one should have a unique `_id` - and that is a ordinary approach since MongoDB indexing work better when the collection has more than 1 million of documents. – BrTkCa Nov 12 '18 at 13:20
  • When you create the document if you don't assign some value for `_id`, the empty value will be a value, so I think you won't can update it, but to be honest I'm not 100% sure about that, I'll make some PoC here.. – BrTkCa Nov 12 '18 at 13:23
  • I've updated my question and found the issue, thanks for contributing tho ! – HRK44 Nov 12 '18 at 13:31
0

_id is an auto generated property for MongoDB. If you want to add try a different name for the Id attribute like "personId" or you can use the auto generated Id by MongoDB without creating a seperate Id.

  • 1
    It is possible to change the type of the ``_id`` field with Mongoose, and that's what I want to do in my case. The question is about the cast error since I'm declaring my _id field as Number and not ObjectId – HRK44 Nov 12 '18 at 13:26