mongoose: The Types.ObjectId type doesn't include a self reference in the _id field

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

7.2.2

Node.js version

16.18.1

MongoDB server version

5.0.13

Typescript version (if applicable)

No response

Description

From: /types/types.d.ts - https://github.com/Automattic/mongoose/blob/master/types/types.d.ts#L82-L84

   class ObjectId extends mongodb.ObjectId {
      _id: this;
    }

Thus, the _id should provide a this reference to itself on the objectId fields on the mongoose documents but instead the ObjectId types are just the mongodb.ObjectId versions and don’t include the _id reference that the mongoose ones are supposed to have

Steps to Reproduce

export interface ITest {
    title: string;
}

const TestSchema = new Schema<ITest>({
       title: {
            type: String,
            required: true,
        },
}

const Test = model<ITest>(TEST_COLLECTION_NAME, TestSchema);

// Create a test doc

//Find the Test doc
const testDoc = await Test.findOne({})
// testDoc._id is the mongodb.ObjectId type but not the mongoose type of Types.ObjectId (missing _id which is supposed to be included in the mongoose type)
// testDoc._id._id is undefined even though the type definition implies a "this" reference should be on the _id field of the objectId

Expected Behavior

_id should be on the Type.ObjectId fields to match the type defn.

   class ObjectId extends mongodb.ObjectId {
      _id: this;
    }

From: /types/types.d.ts - https://github.com/Automattic/mongoose/blob/master/types/types.d.ts#L82-L84

From the example in the steps to reproduce section there should be a this reference on the objectId fields

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 21

Most upvoted comments

@BioSurienDG I took a closer look and you’re right, the issue is that you need to be absolutely sure that your bson version lines up exactly with the one that Mongoose installs if you choose to list bson in “dependencies”. Otherwise you’ll have two separate copies of bson. Better to use mongoose.mongo.BSON, or just import bson from 'bson' without listing bson as a top-level dependency.

Also, it might be good to list the versions of the required libraries in the docs in case someone needs to install them separately?

those versions will change every version and can be easily be found by accessing the package.json either via a git tag or some site like unpkg.com

also, mongodb is accesible through mongoose.mongo and bson is accessible through mongoose.mongo.BSON;

I’m very 😞 @hasezoey that despite reading this entire thread multiple times, it didn’t click me to remove node_modules altogether. Though I tried to delete the lock file before, but deleting node_modules worked. Thanks a ton 🙏🏻

Anyways, to answer your questions-

is MongooseSchema imported from mongoose directly (import { Schema as MongooseSchema } from "mongoose")?

Yes. import mongoose, {Schema as MongooseSchema} from 'mongoose';

what nestjs plugin are you using (@nestjs/mongoose@10.0.0)?

Latest @nestjs/mongoose@10.0.0.

where / how are you using the ObjcetId property and is the type at that point?

I was using it to compare like this- engagement.app._id.equals(currentApp._id).

You should just be able to import mongodb.

yes that would work, but typescript (or something else like a bundler) will complain if not directly installed, if i remember correctly

though it can (without complaints) be imported like import { mongo } from "mongoose" thanks to Mongoose.prototype.mongo = require('mongodb')

https://github.com/Automattic/mongoose/blob/19896c74984f1061c6097a4fcfc28074bb13c641/lib/index.js#LL1186C47-L1186C47