mongoose的行为和模式

目前我正在学习nodejs和mongodb,有两件事让我迷惑。

(1),当使用新的Schema和模型名称(不在db中)时,名称被改为复数forms。 例:

mongoose.model('person', personSchema); 

在数据库中,该表将被称为“人”。 这难道不容易混淆新开发者,为什么他们这样实现呢?

(2)第二件事是,每当我想引用mongoDb中的现有模型(假设在db中,存在一个名为people的表)。 然后在我的nodejs代码中,我仍然需要定义一个Schema来创build一个引用这个表的模型。

 personSchema = new mongoose.Schema({}); mongoose.model('person',personSchema); 

不寻常的是,我如何定义模式似乎并不重要,它可以像上面那样是空的,或者填充随机属性,但是模型总是会得到正确的表,并且CRUD操作正常执行。

那么除了定义表结构来创build新表之外,Schema的用法是什么?

非常感谢,

其实两个问题,你通常会问得更好,以备将来参考。

1.多元化

简而言之,这是一个很好的做法。 更详细地说,这通常是合乎逻辑的,因为您所指的是项目或对象的“集合”。 因此,“集合”中的一般推论是“多”,因此是“对象”本身被命名的复数forms。

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

如果你想用这些forms之一,并且指定你自己的名字,你当然可以改变它:

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

但是模型是一般的“单一”模型名称,“收集”是好的实践的复数forms。 另外,我所能想到的每个SQL数据库ORM也是这样做的。 所以这真的只是遵循大多数人已经习惯的做法。

2.为什么图式?

MongoDB实际上是“无模式的”,所以它没有任何“模式”的内部概念,这是与基于SQL的关系数据库在“表”定义中保留自己的“模式”定义的一个很大的区别。

虽然这通常实际上是MongoDB的一个“优点”,因为数据并不依赖于特定的布局,但有些人实际上喜欢这种方式,或者通常希望封装pipe理数据存储方式的逻辑。

由于这些原因,mongoose支持定义“纲要”的概念。 这允许你说在这个“绑定”的集合(模型)中“哪些字段”是“允许的”,并且可以包含哪个“types”的数据。

你当然可以有一个“无模式”的方法,但是你与模型“绑定”的模式对象仍然必须被定义,而不是“严格”的:

 var personSchema = new Schema({ },{ "strict": false }); mongoose.model( "Person", personSchema ); 

那么你可以添加任何你想要的数据,没有任何限制。

然而,相反的情况是,人们“通常”确实需要执行某种types的规则,例如哪些字段和哪些types。 这意味着只有“定义”的事情才会发生:

 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" } }); 

所以那里的规则分解成:

  1. “name”只能包含“String”数据。 在JavaScript中,所有的JavaScript语言实际上都是串联的。 这里的另一件事是“必需的”,所以如果这个字段不存在于发送给.save()的对象中,它将抛出一个validation错误。

  2. “年龄”必须是数字。 如果你尝试使用这个字段中提供的除数字以外的数据保存.save()这个对象,那么你将抛出一个validation错误。

  3. “性”必须再次成为一个string,但是这次我们增加了一个“约束”来说明有效值是什么。 同样的,如果你不提供正确的数据,这也会导致validation错误。

  4. “children”实际上是一个数组项,但这些只是“引用”ObjectId值,指向另一个模型中的不同项目。 或者在这种情况下,这一个。 所以当你添加到“children”时,这将保持那个ObjectId引用。 实际上,Mongoose可以在需要的时候用实际的“Person”对象.populate() 。 这在MongoDB中模拟了一种“embedded”的forms,但是当你实际上想单独存储对象而不是每次“embedded”时都使用它。

  5. “country”又是一个string,并且不需要任何特殊的内容,但是如果没有其他的显式提供,我们就给它一个缺省值来填充。


还有很多其他的事情可以做,我build议你通过文档阅读。 一切都在那里详细解释,如果你有具体的问题,那么你总是可以问“在这里”(例如)。

因此,MongoDB在SQL数据库的工作方式上做了不同的事情,并抛出了一些通常在“意见”中保留的东西,以便在应用程序业务逻辑层更好地实现。

因此,在Mongoose中,它试图“放回”人们喜欢的关于传统关系数据库的一些好处,并允许一些规则和良好的实践被轻易地封装而不用编写其他代码。

还有一些逻辑有助于“模仿”(不能强调)“连接”,因为有一些方法可以帮助您从其他来源检索“相关”数据,主要是提供哪些“模型“数据驻留在”模式“定义中。

我是否也没有提到“Schema”定义再次只是对象和可重用? 那么是的,他们实际上可以绑定到“很多”模型,可能或不可能驻留在同一个数据库上。

这里的一切都有比你目前所知道的更多的function和目的,在这里它提出了“学习”的好build议。 这是通往实现的通常途径……“哦,现在我明白了,那就是他们这样做的。”