gpt4 book ai didi

javascript - Mongoose 的行为和模式

转载 作者:IT老高 更新时间:2023-10-28 13:25:14 27 4
gpt4 key购买 nike

我目前正在与mongodb一起学习nodejs,有两件事使我有些困惑。

(1),
当使用新的模式和模型名称时(不在db中),该名称将更改为其复数形式。例子:

mongoose.model('person', personSchema);

在数据库中,该表将被称为“人物”。
这难道不容易使新开发人员感到困惑,为什么他们以这种方式实现它?

(2),
第二件事是,每当我想引用mongoDb中的现有模型时(假设在db中,存在一个名为people的表)。然后在我的nodejs代码中,我仍然必须定义一个Schema以便创建引用该表的模型。
personSchema = new mongoose.Schema({});
mongoose.model('person',personSchema);

不寻常的是,如何定义架构似乎无关紧要,它可以像上面一样为空,也可以使用随机属性填充,但是该模型将始终获得正确的表并且CRUD操作可以正常执行。

那么,除了定义用于创建新表的表结构之外,Schema的用途是什么?

非常感谢,

最佳答案

实际上,您通常最好问两个问题,以供将来引用。

1.多元化

简而言之,这是一个好习惯。更详细地说,这通常是合乎逻辑的,因为您所指的是项或对象的“集合”。因此,“集合”中的一般推论是“许多”,因此“对象”本身的名称具有复数形式。

因此,“人”集合意味着它实际上是由许多“人”对象组成的,就像“狗”到“狗”或“猫”到“猫”一样。不一定是“牛”到“牛”,但通常来讲 Mongoose 并不能真正处理多态实体,因此,除非有其他属性将其指定为“牛”,否则那里就不会有“牛”或“野牛”对象。

当然,如果您想使用以下两种形式之一并指定自己的名称,都可以更改此设置:

var personSchema = new Schema({ ... },{ "collection": "person" });

mongoose.model( "Person", personSchema, "person" );

但是,模型通常是“单数”模型名称,而“集合”是良好实践的复数形式(当存在许多情况时)。此外,我能想到的每个SQL数据库ORM都采用这种方式。因此,实际上,这只是遵循 大多数人们已经习惯的做法。

2.为什么要使用模式?

MongoDB实际上是“无模式的”,因此它没有任何“模式”的内部概念,这与基于SQL的关系数据库有很大的不同,后者在“表”定义中保留了自己的“模式”定义。

尽管这实际上是MongoDB的“优势”,因为数据并不局限于特定的布局,但有些人实际上喜欢这种方式,或者通常希望封装控制数据存储方式的逻辑。

由于这些原因, Mongoose 支持定义“模式”的概念。这使您可以说出“绑定(bind)”到该集合(模型)中的“允许”哪些字段,以及可以包含哪些“类型”的数据。

您当然可以采用“无模式”方法,但是仍然必须定义与模型“绑定(bind)”的模式对象,而不必“严格”:
var personSchema = new Schema({ },{ "strict": false });
mongoose.model( "Person", personSchema );

然后,您几乎可以将任何所需内容添加为数据,而没有任何限制。

但是相反的情况是,人们“通常”确实希望强制执行某种类型的规则,例如哪些字段和什么类型。这意味着只能发生“定义的”事情:
var personSchema = new Schema({
name: { type: String, required: true },
age: Number,
sex: { type: String, enum: ["M","F"] },
children: [{ type: Schema.Types.ObjectId, ref: "Person" }],
country: { type: String, default: "Australia" }
});

因此,这里的规则分解为:
  • “名称”中只能包含“字符串”数据。这里有一段JavaScript习惯用法,因为JavaScript中的所有内容实际上都会被字符串化。这里的另一件事是“必需的”,因此,如果在发送给.save()的对象中不存在此字段,它将抛出验证错误。
  • “年龄”必须是数字。如果尝试使用此字段中提供的数字以外的其他数据对对象进行.save()编码,则将引发验证错误。
  • “sex”必须再次为字符串,但是这次我们添加了“constraint”来表示有效值是什么。同样,如果您没有提供正确的数据,这也会引发验证错误。
  • “子级”实际上是项目的数组,但是这些只是指向另一个模型中不同项目的“引用” ObjectId值。或者在这种情况下就是这个。因此,当您添加到“子项”时,它将把该ObjectId引用保留在其中。当需要时, Mongoose 实际上可以稍后用其实际的“Person”对象对它们进行.populate()编码。这在MongoDB中模拟了一种“嵌入”形式,但是当您实际上要单独存储对象而不每次都“嵌入”时使用。
  • “country”仍然只是一个String,不需要任何特殊内容,但是如果没有其他显式提供的值,我们将为它提供一个默认值以进行填充。


  • 您还可以执行许多其他操作,建议您通过 the documentation阅读。在那里对所有内容进行了详细的解释,如果您有特定的问题,则可以随时问“这里”(例如)。

    因此,MongoDB所做的事情与SQL数据库的工作方式有所不同,并且抛出了通常保存在“意见”中的某些事情,以便无论如何都可以在应用程序业务逻辑层更好地实现。

    因此,在Mongoose中,它试图“退回”人们喜欢使用传统关系数据库的一些好东西,并允许轻松编写一些规则和良好实践,而无需编写其他代码。

    还有一些逻辑可以帮助“模拟”(压力不够大)“联接”,因为有一些方法可以“帮助”您从其他来源检索“相关”数据,方法是提供一些定义,其中“数据驻留在“架构”定义中的“模型”。

    我是否还没有提到“模式”定义又只是对象并且可以重用?嗯,是的,它们实际上可以绑定(bind)到“许多”模型,这些模型可以或可以不驻留在同一数据库中。

    这里的一切功能和目的都比您目前所知道的要多得多,这里的好建议是继续学习。那是实现这一目标的通常途径。“哦,现在我明白了,这就是他们这样做的方式”。

    关于javascript - Mongoose 的行为和模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24668976/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com