30

有没有办法在猫鼬中声明模型模式,这样当模型是新的时,_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。但如果我查看数据库,它确实包含它。

ps 我正在使用猫鼬 2.7.1

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

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

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

4

5 回答 5

30

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

于 2012-07-23T00:08:16.603 回答
28

添加auto标志:

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

来源

于 2017-03-07T14:11:09.120 回答
15

代替:

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

你应该做:

_id:    {type:ObjectIdSchema, default: function () { return new ObjectId()} }
于 2014-01-18T13:46:37.097 回答
9

取自官方 MongoDB 手册和文档:

_ID

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


对象 ID

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

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

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

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

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

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

明确声明_id

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

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

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


TL;博士

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

于 2019-02-02T16:34:12.073 回答
0

这是做到这一点的好方法

在模型中:

const schema = new Schema({ userCurrencyId:{type: mongoose.Schema.Types.ObjectId,
        index: true,
        required: true,
        auto: true});
于 2021-03-17T12:28:20.060 回答