82

What is the difference between _id and id in mongoose? Which is better for referencing?

Community
  • 1
  • 1
Ari Porad
  • 2,834
  • 3
  • 33
  • 51

1 Answers1

129

From the documentation:

Mongoose assigns each of your schemas an id virtual getter by default which returns the documents _id field cast to a string, or in the case of ObjectIds, its hexString.

So, basically, the id getter returns a string representation of the document's _id (which is added to all MongoDB documents by default and have a default type of ObjectId).

Regarding what's better for referencing, that depends entirely on the context (i.e., do you want an ObjectId or a string). For example, if comparing id's, the string is probably better, as ObjectId's won't pass an equality test unless they are the same instance (regardless of what value they represent).

jmar777
  • 38,796
  • 11
  • 66
  • 64
  • please see revised question – Ari Porad Mar 30 '13 at 23:25
  • 1
    As far as what's better for referencing, that depends entirely on the context (i.e., do you want an `ObjectId` or a `string`). For example, if comparing `id`'s, the string is probably better, as `ObjectId`'s won't pass an equality test unless they are the same instance (regardless of what value they represent). – jmar777 Mar 31 '13 at 03:17
  • 5
    @jmar777 The ObjectId does have an `equals` method which can be used for comparison. – Lucky Soni Jan 03 '15 at 19:21
  • 1
    Watch out for nested documents. Mongoose won't assign the `id` virtual to nested objects, even though they have an `_id` field with an ObjectId. – Elad Nava Sep 12 '15 at 19:13
  • @EladNava Does that mean if you want one document to reference another, you should assign a custom field the model that references the _id field? – AlxVallejo Dec 14 '15 at 21:56
  • @AlxVallejo Not necessarily, you just need to read from the `_id` field yourself and convert it from an `ObjectId` to a `string`. – Elad Nava Dec 15 '15 at 08:01
  • So in short book.id === string and book._id === ObjectId, just putting this out for future reference :) – Woppi Jul 27 '18 at 06:03
  • I've spent a lot of time without knowing this. I just used _id.toString() all the time, lol. It's really important to read the documentation... – Luis May 16 '23 at 21:18
  • The flipside of the 'comparing a string' use case is using aggregate().match() which expects an ObjectId, so `_id` is the prefered, or else generating an ObjectId from a string with `mongoose.Types.ObjectId(string)` – hughc May 24 '23 at 12:50