在Mongoose中,_id
是一个文档的默认主键,而 id
是 ObjectId
类型的 _id
字段的虚拟访问器。
详细解释如下:
_id
- 每个在MongoDB中创建的文档都有一个唯一的
_id
字段,这个字段在文档创建时自动生成。 _id
字段默认是一个ObjectId
对象,它是一个十二字节的唯一值,MongoDB使用这个字段作为主键。ObjectId
包含了时间戳(文档创建的时间),机器标识码,MongoDB服务进程id和序列号,这些可以保证在分布式系统中_id
的唯一性。
id
id
是Mongoose为_id
字段提供的虚拟属性,它其实就是_id
的字符串表示形式。- 访问
id
属性时,Mongoose会调用_id
字段的.toString()
方法,将其转换为24字符的十六进制字符串。 - 因为
id
是虚拟生成的,所以它并不实际存在于MongoDB数据库中,仅仅是Mongoose层面给予的便利。
使用场景
当你需要在程序中使用文档的主键时,直接使用 _id
字段就可以了。如果你需要将文档的主键以字符串形式发送到前端或者作为URL的一部分,比如在RESTful API中通常使用字符串格式的ID,那么就可以使用 id
属性。
示例
假设你有一个用户文档,其 _id
字段是 ObjectId('507f191e810c19729de860ea')
,你可以这样访问该文档的ID:
javascriptconst user = await User.findById('507f191e810c19729de860ea'); console.log(user._id); // 打印 ObjectId('507f191e810c19729de860ea') console.log(user.id); // 打印 '507f191e810c19729de860ea' 的字符串形式
在上述代码中,user._id
返回的是 ObjectId
对象,而 user.id
返回的是相应的字符串形式。当你需要将这个ID以纯文本格式传递或者展示时,id
属性就非常有用了。
总之,_id
是数据库中文档的实际主键,而 id
是一个方便我们使用的虚拟属性。