【问题标题】:is there a way to auto generate ObjectId when a mongoose Model is new'ed?当猫鼬模型是新的时,有没有办法自动生成 ObjectId?
【发布时间】:2012-07-21 05:45:41
【问题描述】:

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

例如:

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);

一开始,我觉得很棒!,我会做的

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

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

那么有没有办法让我每次执行“new Person()”时都会生成一个新的 ObjectId()?

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

我也试过了:

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

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

附言我正在使用猫鼬 2.7.1

p.p.s.我知道我可以在创建人时手动创建 ObjectId:

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

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

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    这是一个很好的方法

    在模型中:

    const schema = new Schema({ userCurrencyId:{type: mongoose.Schema.Types.ObjectId,
            index: true,
            required: true,
            auto: true});
    

    【讨论】:

      【解决方案2】:

      取自官方 MongoDB 手册和文档:

      _id

      每个 MongoDB 文档中都需要一个字段。 _id 字段必须有一个 独特的价值。您可以将_id 字段视为文档的主要字段 钥匙。如果您创建一个没有 _id 字段的新文档,MongoDB 自动创建字段并分配一个唯一的 BSON ObjectId。
      Source


      对象ID

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

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

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

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

      重要提示
      虽然 ObjectId 值应该增加超过 时间,它们不一定是单调的。这是因为他们:

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

      显式声明_id:

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

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

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


      TL;DR

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

      【讨论】:

      • 这是准确的答案,也是唯一有效的方法。谢谢
      【解决方案3】:

      添加auto 标志:

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

      source

      【讨论】:

      • 无需明确指定_idIn MongoDB, each document stored in a collection requires a unique _id field that acts as a primary key. If an inserted document omits the _id field, the MongoDB driver automatically generates an ObjectId for the _id field.Read the docs
      【解决方案4】:

      代替:

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

      你应该这样做:

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

      【讨论】:

      • 这是不必要的......如果你不指定_id是什么,它默认为ObjectId并创建自己
      • [错误:文档必须有_id才能保存]
      • 这个答案仍然有用,因为例如子文档没有自动生成的_id
      • 这仍然是实际的,尤其是对于 dockerized mongo 图像
      【解决方案5】:

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

      【讨论】:

      • 是的,并且不需要在架构中包含_id 字段。
      • @JohnnyHK,你和 Last Rose Studios 是对的。就像你说的那样。我注释掉了“_id:ObjectIdSchema”这一行,当我新建 Person() 时,它就有了 id!但是当我没有注释掉它时,id 就永远不会生成。多谢你们!非常感谢。
      • 对于新观众,这种行为自那以后有改变吗?今天我不得不提到default: new mongoose.Types.ObjectId(),如果我在模型架构中添加_id,它就不起作用了!
      • 我可以回显上面的 cmets,使用节点版本 4.8.1 ,如果 _id 在 Schema 中声明,_id 不会自动生成
      猜你喜欢
      • 1970-01-01
      • 2020-07-25
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 2013-07-27
      • 2013-07-04
      • 2020-03-31
      相关资源
      最近更新 更多