Search code examples
typescriptmongodbmongoosetypegoose

Can't omit _id field in findOneAndUpdate operation


I have a function for updating mongoDB documents. After making manipulations to the sent data, I update wanted document using mongoose's findOneAndUpdate function. Since I'll be using saved data I've set new:true and use object named userReturnFormat as projection to retrieve necessary fields. Code example:

const userReturnFormat = {
    email: 1,
    name: 1,
    surname: 1,
    _id: 0
}

const updatedUser = (await UserModel.findOneAndUpdate(
            { registerId: params.user.registerId },
            { $set: data },
            { new: true, projection: userReturnFormat }
        )) as User

As you can see from userReturnFormat object _id field is marked as false. When I use {_id:0} as the projection it successfully omits _id field. I've tried directly writing projection inside update operation but it still returns _id field when I mark any property as true. I can use delete operand to remove _id field after updating document but I don't want to use this since projection should be able to be used for this purpose.

{_id: 0 } as projection:

const updatedUser = (await UserModel.findOneAndUpdate(
            { registerId: params.user.registerId },
            { $set: data },
            { new: true, projection: { _id: 0 } }
        )) as User

RESULT:

{
  email: ‘[email protected]’,
  password: ‘HASHED_PASSWORD’,
  name: ‘JOHN’,
  surname: ‘DOE’,
  type: ‘example’,
  createdAt: 2024-01-03T12:57:20.972Z,
  updatedAt: 2024-01-04T07:30:27.153Z
}

Using delete operand:

const updatedUser = (
            await UserModel.findOneAndUpdate({ registerId: params.user.registerId }, { $set: data }, { new: true, projection: userReturnFormat })
        )?._doc

delete updatedUser._id

RESULT:

{
  email: ‘[email protected]’,
  name: ‘JOHN’,
  surname: ‘DOE’,
}

Solution

  • Try with select:

    await UserModel.findOneAndUpdate(
       { registerId: params.user.registerId },
       { $set: data },
       { new: true }
    ).select(userReturnFormat).exec();