当mongoose模型是新的时,有没有办法自动生成ObjectId?

时间:2012-07-22 23:47:58

标签: node.js mongodb mongoose

有没有办法在mongoose中声明一个Model模式,这样当模型新建时,_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()}

但当然这不起作用,因为新的ObjectId()仅在初始化模式时调用。所以调用两个新的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。但如果我查看数据库,它确实包含它。

P.S。我正在使用mongoose 2.7.1

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

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

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

5 个答案:

答案 0 :(得分:24)

你调用var person = new Person(); person._id应该给你id(即使它尚未保存)。只是实例化它就足以给它一个id。你仍然可以保存它,并且它将存储id以及人物对象的其余部分

答案 1 :(得分:18)

添加auto标志:

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

source

答案 2 :(得分:10)

而不是:

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

你应该这样做:

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

答案 3 :(得分:2)

从官方MongoDB的手册和文档摘自:

_id

  

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


ObjectID

  

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

     

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

     

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

     

MongoDB客户端应添加带有唯一 ObjectId _id字段。   在_id字段中使用ObjectIds提供了以下附加功能   好处:在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。

答案 4 :(得分:0)

这是一个很好的方法

在模型中:

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