当猫鼬模型是新的时,有没有办法自动生成 ObjectId?
Posted
技术标签:
【中文标题】当猫鼬模型是新的时,有没有办法自动生成 ObjectId?【英文标题】:is there a way to auto generate ObjectId when a mongoose Model is new'ed? 【发布时间】: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 字段创建值。
【问题讨论】:
【参考方案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
【讨论】:
无需明确指定_id
:In 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 不会自动生成以上是关于当猫鼬模型是新的时,有没有办法自动生成 ObjectId?的主要内容,如果未能解决你的问题,请参考以下文章