Mongoose行为和架构

时间:2014-07-10 05:19:40

标签: javascript node.js mongodb mongoose database-schema

我目前正在和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 个答案:

答案 0 :(得分:12)

实际上有两个问题,你通常会更好地问一个问题,以备将来参考。

1。复数

简短形式是好的做法。更详细地说,这通常是合乎逻辑的,因为你所指的是一个"集合"相反的项目或对象。因此,"集合中的一般推论"很多"很多"因此是一个复数形式的"对象"本身就是这个名字。

所以"人们"收集意味着它实际上是由许多人组成的#34;对象,就像"狗"去#34;狗"或者"猫"到" cat"。不一定" bovines" to" cow",但一般来说mongoose并不真正处理多态实体,所以不会有" bull"或者"野牛"除非只是由其他一些财产指定给"牛"。

如果你想要这些表格中的任何一个并指定你自己的名字,你当然可以改变这个:

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

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

但是模型是一般的"单数"型号名称和"集合"当有很多时,它是多元形式的良好实践。此外,我能想到的每个SQL数据库ORM也都是这样做的。所以,这只是遵循大多数人已经习惯的做法。

2。为什么是Schema?

MongoDB实际上是"无模式",因此它没有" schema"的任何内部概念,这与基于SQL的关系数据库有一个很大的区别,它们拥有自己的& #34;模式"在"表"定义

虽然这通常是一种强度" MongoDB中的数据并不依赖于某种布局,有些人实际上喜欢这种方式,或者通常希望以其他方式封装管理数据存储方式的逻辑。

由于这些原因,mongoose支持定义" Schema"的概念。这允许你说"哪些字段"被允许"在集合(模型)中,这是"捆绑"到,和#34;键入"可能包含数据。

你当然可以拥有一个"无模式的"方法,但架构对象,你" tie"你的模型仍然必须定义,严格来说不是":

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

所以那里的规则分解为:

  1. "名称"必须有" String"仅包含数据。这里有一些JavaScript习惯用法,因为JavaScript中的所有内容都会实际字符串化。另一件事是"必需",因此如果发送到.save()的对象中不存在此字段,则会产生验证错误。

  2. "年龄"必须是数字。如果您尝试使用此字段中提供的数字以外的数据.save()此对象,则会抛出验证错误。

  3. "性别"必须再次成为一个字符串,但这次我们正在添加一个"约束"说出有效值是什么。同样,如果您不提供正确的数据,这也会引发验证错误。

  4. "的子"实际上是一个项目数组,但这些只是"参考" ObjectId值指向另一个模型中的不同项。或者在这种情况下这一个。因此,当您添加到" children"时,这将在那里保留ObjectId引用。事实上,猫鼬实际上可以.populate()以及他们实际的#34; Person"请求时的对象。这模仿了一种形式的嵌入"在MongoDB中,但是当你真正想要单独存储对象而没有"嵌入"每一次。

  5. "国家"再次只是一个字符串并且不需要任何特殊内容,但如果没有明确提供其他内容,我们会给它一个默认值来填写。


  6. 你还可以做很多其他的事情,我建议你仔细阅读the documentation。一切都在那里详细解释,如果你有具体的问题,那么你总是可以问," here" (例如)。

    因此,MongoDB对SQL数据库的工作方式做了不同的处理,并抛出了一些通常存在于"意见"无论如何,要在应用程序业务逻辑层更好地实现。

    因此,在Mongoose中,它试图“放回”#34;人们喜欢使用传统关系数据库的一些好东西,并允许在不编写其他代码的情况下轻松封装某些规则和良好实践。

    还有一些逻辑可以帮助模仿" (不能强调压力)"加入",因为有方法可以帮助"你能够检索到相关的"来自其他来源的数据,基本上提供定义,其中"模型"该数据位于" Schema"定义

    我是否也没有提及" Schema"定义又是对象和可重用的?嗯,是的,他们实际上可以与#34;很多"模型,可能存在也可能不存在于同一数据库中。

    这里的所有功能和目的都比您目前所了解的要多得多,这里提出的建议很好,并且学习"。这是实现的通常途径......"哦,现在我明白了,那就是他们这样做的方式"。