Javascript 猫鼬行为与图式

Javascript 猫鼬行为与图式,javascript,node.js,mongodb,mongoose,database-schema,Javascript,Node.js,Mongodb,Mongoose,Database Schema,目前我正在和mongodb一起学习NodeJ,有两件事让我有点困惑 (1) ,, 当使用新的模式和模型名称时(不在db中),名称将更改为复数形式。例如: mongoose.model('person', personSchema); 在数据库中,该表将被称为“people”。 这不容易让新开发人员感到困惑吗?他们为什么要这样实现它 (2) ,, 第二件事是,每当我想引用mongoDb中的现有模型时(假设在db中存在一个名为people的表)。然后在我的nodejs代码中,我仍然必须定义一个模式

目前我正在和mongodb一起学习NodeJ,有两件事让我有点困惑

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

mongoose.model('person', personSchema);
在数据库中,该表将被称为“people”。 这不容易让新开发人员感到困惑吗?他们为什么要这样实现它

(2) ,, 第二件事是,每当我想引用mongoDb中的现有模型时(假设在db中存在一个名为people的表)。然后在我的nodejs代码中,我仍然必须定义一个模式,以便创建一个引用表的模型

personSchema = new mongoose.Schema({});
mongoose.model('person',personSchema);
不寻常的是,我如何定义模式似乎并不重要,它可以像上面那样为空,也可以用随机属性填充,但是模型将始终获得正确的表,CRUD操作将正常执行

那么,除了定义用于创建新表的表结构之外,模式还有什么用途


非常感谢,

实际上是两个问题,你最好问一个,仅供将来参考

1.多元化 简而言之,这是一种良好的做法。更详细地说,这通常是合乎逻辑的,因为您所指的是项目或对象的“集合”,而不是。因此,“集合”中的一般推论是“多”,因此是“对象”本身名称的复数形式

因此,“人”集合意味着它实际上由许多“人”对象组成,就像“狗”到“狗”或“猫”到“猫”一样。不一定是“牛”到“牛”,但一般来说,猫鼬并不真正处理多态实体,因此不会有“牛”或“野牛”对象,除非只是由其他属性指定为“牛”

当然,如果您想在以下任一形式中更改此项,并指定您自己的姓名:

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

mongoose.model( "Person", personSchema, "person" );
但是一个模型通常是一个“单数”模型名称,“集合”是良好实践的复数形式。此外,我能想到的每个SQL数据库ORM都是这样做的。因此,实际上这只是遵循大多数人已经习惯的做法

2.为什么是模式? MongoDB实际上是“无模式的”,因此它没有任何“模式”的内部概念,这与基于SQL的关系数据库有很大区别,后者在“表”定义中保留自己的“模式”定义

虽然这实际上是MongoDB的一个“优势”,因为数据不绑定到特定的布局,但有些人实际上喜欢这种方式,或者通常希望以其他方式封装控制数据存储方式的逻辑

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

当然,您可以使用“无模式”方法,但您“绑定”到模型的模式对象仍然必须定义,只是不能“严格定义”:

然后,您几乎可以不受任何限制地添加任何您想要的数据

相反的情况是,人们“通常”确实希望强制执行某种类型的规则,例如哪些字段和哪些类型。这意味着只有“定义”的事情才能发生:

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”必须再次成为字符串,但这次我们添加了一个“约束”来说明有效值是什么。同样,如果您没有提供正确的数据,这也会引发验证错误

  • “子对象”实际上是一个项目数组,但它们只是指向另一个模型中不同项目的“引用”ObjectId值。或者在这个例子中是这个。因此,当您添加到“children”时,这将保留ObjectId引用。Mongoose实际上可以
    .populate()
    稍后在请求时使用实际的“Person”对象来填充这些对象。这模拟了MongoDB中的一种“嵌入”形式,但在实际需要单独存储对象而不是每次都“嵌入”时使用

  • “country”同样只是一个字符串,不需要任何特殊设置,但如果没有明确提供其他值,我们会给它一个默认值来填充


  • 你还可以做很多其他的事情,我建议你仔细阅读。每件事都有详细的解释,如果你有具体的问题,你可以问“这里”(例如)

    因此,MongoDB的工作方式与SQL数据库的工作方式不同,并且抛弃了一些通常被认为是“意见”的东西,以便更好地在应用程序业务逻辑层实现

    因此,在Mongoose中,它试图“还原”人们喜欢使用传统关系数据库的一些优点,并允许在不编写其他代码的情况下轻松封装一些规则和良好实践

    还有一些逻辑有助于“模拟”(强调不够)“连接”,因为有一些方法“帮助”您能够从其他源检索“相关”数据,基本上是提供定义,其中数据位于“模式”定义中的“模型”

    我还没有提到“模式”定义同样只是对象和可重用的吗?是的,它们是一个可以与“许多”模型联系在一起的模型,这些模型可能存在也可能不存在于同一个数据库中

    这里的一切都有着比你现在所意识到的更多的功能和目的,这里的好建议是向前走和“学习”。这就是问题所在
    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" }
    });