如何在Mongoose中定义一个不同于_id的主键?

14

我想使用非_id的主键来定义Mongoose模式。文档表示仅允许在子文档中将模式选项标志_id设置为false。同时,我希望主键是String而不是ObjectId。这有可能吗?

使用二级索引是一个选项,但并不理想,因为我希望有适当名称的主键。我也不想在不需要的情况下使用两个不同的索引。

这会将documentId设置为次要索引,但这使得主键无效,因为我只想通过documentId选择,而不是自动设置为_id的任何东西。

const DocumentSchema = new Schema({
  documentId: { type: String, index: true }
})

我想做类似于

const DocumentSchema = new Schema({
  documentId: String
})

然后告诉它使用 documentId 作为主键。

澄清:我特意不想使用 _id 作为键,因为它的名称不够明确,我想使用 documentId 作为主键代替。

4个回答

10

在模式阶段,您可以手动定义_id字段,例如:

const DocumentSchema = new Schema({
  _id: String //or number, or (increment) function,
  ...
  other_field: BSON_type,
})

Nestjs 更新

如果要手动重写或定义模式中的 _id 字段,请使用以下示例:

/**
 * extends Document is a Mongoose Document from 'mongoose'
 * and don't forget about Nest Schema decorator
 */
@Schema()
export class Key extends Document { 
  @Prop({ type: String }) // also can be Number, or Decimal128
  _id: string; // number

  @Prop({ type: String, required: true })
  secret: string;
}

通过@Prop({ _id: false })禁用子文档中的_id

如果您正在寻找一个带有_id示例的嵌入式文档数组,您可能需要查看我的其他问题。

insert阶段之前将_id值添加到您的文档中,或通过您的函数或npm模块(如此类)在schema部分生成它。您唯一需要确保的是,您自定义生成的_id值必须是唯一的。如果它们不是唯一的,Mongo在插入没有唯一_id值的文档时会返回错误。


1
我已经有一种生成文档ID的方法,我只想将它们存储在名为documentId而不是_id的字段中。但如果这不可能,将_id定义为字符串类型是否可以? - douira
@douira 我刚刚添加了这部分到答案中,之前没有看到问题的 澄清 部分。 - AlexZeDim
可能是我的问题,我认为这个问题已经很清楚地表明我想要称它为documentId而不是_id - douira

4
在MongoDB中,没有主键。你只需要一个唯一的索引,就可以开始工作了。
const DocumentSchema = new Schema({
  _id: false,
  documentId: {
    type: String,
    unique: true,
    required: true
  }
})

请看https://mongoosejs.com/docs/schematypes.htmlhttps://docs.mongodb.com/manual/core/index-unique/

唯一索引确保索引字段不存储重复的值;即针对索引字段强制唯一性。默认情况下,MongoDB在创建集合时会在_id字段上创建唯一索引。


2
哦,所以我只需要定义一个二级索引,使其唯一,那么我就有了类似主索引的东西? - douira
1
是的,正确的。我的项目中有很多这样的东西。话虽如此,这将会破坏 Model.findById。你必须使用 Model.findOne({ documentId: 'unique_key' }) 查询事物。 - sunknudsen
1
@douira 对的,就是这样,但不要忘记如果你导入文档时没有该字段,MongoDB会返回错误,因此我强烈推荐你使用类似于这样的方式:https://dev59.com/GV4c5IYBdhLWcg3wEGt_。这将在模式期间生成您的自定义ID。 - AlexZeDim
1
@douira 不需要,unique: true 会为你创建索引。请参见 https://mongoosejs.com/docs/schematypes.html 和 https://docs.mongodb.com/manual/core/index-unique/. - sunknudsen
5
我发现所有的文件都必须有一个 _id 键才能使mongoose起作用。如果没有这个键,mongoose将会出错。我现在将 _id 字段简单地声明为字符串。 - douira
显示剩余3条评论

4
const Schema = new Schema({
  _id: false,
  Id: {
    type: String,
    unique: true,
    index: true,
    required: true,
  },
});

3

索引是最好的实现方式。实际上,_id 也是一个索引。尝试创建如下所示的索引:

documentSchema.index({ 'documentId' : 1 }, { unique: true });

Refer : https://docs.mongodb.com/manual/indexes/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接