node.js 当猫鼬模型被新建时,有没有办法自动生成 ObjectId?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11604928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:03:36  来源:igfitidea点击:

is there a way to auto generate ObjectId when a mongoose Model is new'ed?

node.jsmongodbmongoose

提问by Khon

is there a way to declare a Model schema in mongoose so that when the model is new'ed the _id field would auto-generate?

有没有办法在 mongoose 中声明模型模式,以便在模型新建时 _id 字段会自动生成?

for example:

例如:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectIdSchema = Schema.ObjectId;
var ObjectId = mongoose.Types.ObjectId;

var PersonSchema = new Schema({
    _id:            ObjectIdSchema,
    firstName:      {type: String, default: 'N/A'},
    lastName:       {type: String, default: 'N/A'},
    age:            {type: Number, min: 1}
});

var Person = mongoose.model('Person', PersonSchema);

at first, i thought great!, i'll just do

起初,我觉得很棒!我就去做

_id:    {type:ObjectIdSchema, default: new ObjectId()}

but of course that doesn't work, because new ObjectId() is only called on initialize of schema. so calling new Persion() twice creates two objects with the same _id value.

但当然这不起作用,因为 new ObjectId() 仅在架构初始化时调用。所以调用 new Persion() 两次会创建两个具有相同 _id 值的对象。

so is there a way to do it so that every time i do "new Person()" that a new ObjectId() is generated?

那么有没有办法做到这一点,以便每次我执行“new Person()”时都会生成一个新的 ObjectId()?

the reason why i'm trying to do this is because i need to know the value of the new person's _id value for further processing.

我尝试这样做的原因是因为我需要知道新人的 _id 值的值以进行进一步处理。

i also tried:

我也试过:

var person = new Person({firstName: "Joe", lastName: "Baz"});
person.save(function(err, doc, num){
    console.log(doc._id);
});

even then, doc doesn't contain the ObjectId. but if i look in the database, it does contain it.

即便如此,doc 也不包含 ObjectId。但如果我查看数据库,它确实包含它。

p.s. i'm using mongoose 2.7.1

ps 我使用的是猫鼬 2.7.1

p.p.s. i know i can manually create the ObjectId when creating the person as such:

pps 我知道我可以在创建这样的人时手动创建 ObjectId:

var person = new Person({_id: new ObjectId(), firstName: "Joe", lastName: "Baz"});

but i rather not have to import ObjectId and have to new it every time i want to new a Person. guess i'm used to using the java driver for mongodb, where i can just create the value for the _id field in the Model constructor.

但我宁愿不必导入 ObjectId 并且每次我想新建一个人时都必须新建它。我猜我习惯于使用 mongodb 的 java 驱动程序,我可以在模型构造函数中为 _id 字段创建值。

回答by Last Rose Studios

the moment you call var person = new Person(); person._id should give you the id (even if it hasn't been saved yet). Just instantiating it is enough to give it an id. You can still save it after, and that will store the id as well as the rest of the person object

当你调用 var person = new Person(); person._id 应该给你 id(即使它还没有被保存)。仅仅实例化它就足以给它一个 id。之后您仍然可以保存它,这将存储 id 以及 person 对象的其余部分

回答by yishaiz

Add the autoflag:

添加auto标志:

_id: {
    type: mongoose.Schema.Types.ObjectId,
    index: true,
    required: true,
    auto: true,
  }

source

来源

回答by user3209935

Instead of:

代替:

_id:    {type:ObjectIdSchema, default: new ObjectId()}

You should do:

你应该做:

_id:    {type:ObjectIdSchema, default: function () { return new ObjectId()} }

回答by user0800

Taken from the official MongoDB Manual and Docs:

摘自官方 MongoDB 手册和文档:

_id

_ID

A field required in every MongoDB document. The _idfield must have a unique value. You can think of the _idfield as the document's primary key. If you create a new document without an _idfield, MongoDB automatically creates the field and assigns a unique BSON ObjectId.
Source

每个 MongoDB 文档中都需要的字段。该_id字段必须具有唯一值。您可以将该_id字段视为文档的主键。如果您创建一个没有_id字段的新文档,MongoDB 会自动创建该字段并分配一个唯一的 BSON ObjectId。
来源



ObjectID

对象ID

ObjectIds are small, likely unique, fast to generate, and ordered. ObjectIdvalues consist of 12 bytes, where the first four bytes are a timestamp that reflect the ObjectId's creation. Specifically:

a 4-byte value representing the seconds since the Unix epoch, a 5-byte random value, and a 3-byte counter, starting with a random value. In MongoDB, each document stored in a collection requires a unique _idfield that acts as a primary key. If an inserted document omits the _idfield, the MongoDB driver automatically generates an ObjectIdfor the _idfield.

This also applies to documents inserted through update operations with upsert: true.

MongoDB clients should add an _idfield with a unique ObjectId. Using ObjectIds for the _idfield provides the following additional benefits: in the mongo shell, you can access the creation time of the ObjectId, using the ObjectId.getTimestamp()method. sorting on an _id field that stores ObjectId values is roughly equivalent to sorting by creation time.

IMPORTANT
While ObjectIdvalues should increase over time, they are not necessarily monotonic. This is because they:

Only contain one second of temporal resolution, so ObjectIdvalues created within the same second do not have a guaranteed ordering, and Are generated by clients, which may have differing system clocks.
Source

ObjectIds 很小,可能是唯一的,生成速度快,并且有序。 ObjectId值由 12 个字节组成,其中前四个字节是反映 ObjectId 创建的时间戳。具体来说:

一个 4 字节的值表示自 Unix 纪元以来的秒数,一个 5 字节的随机值和一个 3 字节的计数器,从一个随机值开始。在 MongoDB 中,存储在集合中的每个文档都需要一个_id充当主键的唯一字段。如果插入的文档省略了该 _id字段,MongoDB 驱动程序会自动 为该字段生成一个ObjectId_id

这也适用于通过 upsert: true 的更新操作插入的文档。

MongoDB 客户端应该添加一个_id具有唯一ObjectId的字段。将 ObjectIds 用于_id字段提供了以下额外好处:在 mongo shell 中,您可以使用方法访问ObjectId的创建时间 ObjectId.getTimestamp()。对存储 ObjectId 值的 _id 字段进行排序大致相当于按创建时间排序。

重要
虽然ObjectId值应该随着时间的推移而增加,但它们不一定是单调的。这是因为他们:

仅包含一秒的时间分辨率,因此在同一秒内创建的ObjectId值没有保证的顺序,并且由客户端生成,客户端可能具有不同的系统时钟。
来源

Explicitly declaring _id:

明确声明_id

When explicitly declaring the _idfield, specify the autooption:

显式声明_id字段时,指定auto选项:

new Schema({ _id: { type: Schema.ObjectId, auto: true }})

ObjectId only - Adds an auto-generated ObjectId default if turnOn is true.
Source

ObjectId only - 如果 turnOn 为 true,则添加自动生成的 ObjectId 默认值。
来源



TL;DR

TL; 博士

If you create a new document without an _id field, MongoDB automatically creates the field and assigns a unique BSON ObjectId.

如果您创建一个没有 _id 字段的新文档,MongoDB 会自动创建该字段并分配一个唯一的 BSON ObjectId。