有效的mongodb + mongoose。架构设计
Posted
技术标签:
【中文标题】有效的mongodb + mongoose。架构设计【英文标题】:Effective mongodb + mongoose. Schema design 【发布时间】:2014-02-04 09:20:32 【问题描述】:我是 mongodb 和 nosql 数据库的新手。我真的很感谢我的架构设计的一些输入/帮助,所以我不会在脚下开枪。
数据:我需要为Quote
s 建模。一个Quote
包含许多Ttem
s。每个Item
包含许多Order
s。每个Order
都与特定的财政季度相关联。 例如。我有一个Quote
,其中包含一个Item
,它在Q3-14、Q4-14、Q1-15中有Order
s。 Order
s 只在未来 12 个季度(3 年)内max。具体来说,我在建模Order
-quarter 绑定时遇到了麻烦。我正在尝试对数据进行非规范化并嵌入 Quote
Items Orders 以获得性能。
尝试/想法:
-
拥有一个包含
year
和qNum
字段的Order
架构。在每个 Item
中嵌入一个 Orders
数组。还可以创建虚拟qKey
字段,用于通过Q1-14
等字符串进行设置/获取
使用Q1-14
之类的键创建一个将Order
s 嵌入Item
的哈希。这会很好,但 Mongoose 本身不支持。
将当前(基本)季度存储在每个Quote
中,并让每个Item
包含一个Order
s 数组,但让它们按从基本季度偏移的#quarters 索引。 IE。如果当前是 Q1-14,并且有 Q4-14 的订单进来,则将其存储在数组位置 2 中。
我完全偏离了标记吗?感谢任何建议,因为我很难有效地使用 Mongo。谢谢
【问题讨论】:
我能问一下,当您的数据是关系型数据时,您为什么选择 Mongo 而不是传统的 RDBMS? @jibsales 我正在使用 Node.js,并且可以在 mongo 或 mssql 之间进行选择。 Mongo 似乎在节点社区风靡一时,所以我想我会尝试一下。此外,目前没有可用于带有节点的 mssql 的 ORM。此外,完整的 JSON/JS 堆栈似乎很诱人。 【参考方案1】:免责声明:我开始这只是对自己的挑战。请参阅下面的
<rant>
,了解我不同意您的方法的原因。
牢牢掌握 No-SQL 的第一步是抛弃诸如“非规范化”之类的术语——它们根本不适用于基于文档的数据存储。另一个需要理解的重要概念是 MongoDB 中没有JOINS
,因此您必须完全改变对数据的看法才能进行调整。
解决mongoose
问题的最佳方法是分别为报价和项目设置集合。然后我们可以在这些集合之间设置引用以将文档“链接”在一起。
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var quoteSchema = new Schema(
items: [ type: Schema.Types.ObjectId, ref: 'Item' ]
);
var itemSchema = new Schema();
处理您的报价 -> 项目“关系”。要设置订单,您可以使用您所指出的嵌入文档数组,但如果您决定开始查询/索引订单,您将在没有桨的情况下走上一条小河.同样,我们可以通过引用来解决这个问题:
var itemSchema = new Schema(
orders: [ type: Schema.Types.ObjectId, ref: 'Order' ]
);
var orderSchema = new Schema(
quarter: String
);
现在你可以使用人口来获得你需要的东西:
Item
.findById(id)
.populate(
path: 'orders',
match: quarter: 'Q1-14'
)
.exec(function (err, item)
console.log(item.orders); // logs an array of orders from Q1-14
);
引用的问题在于,您实际上两次使用读取指令访问数据库,一次是查找父文档,然后一次是填充其引用。
您可以在此处阅读有关参考和人口的更多信息:http://mongoosejs.com/docs/populate.html
<rant>
我可以持续几个小时,为什么您应该坚持使用 RDBMS 来处理此类数据。特别是当辩护的选择是缺乏orm和mongo是“所有的愤怒”。工程师为解决方案选择最好的技术,而不是因为某种技术正在流行。它是周末黑客和创建企业级产品之间的区别。不要误会我的意思,这不是要丢弃 No-SQL——我维护的最大代码库是基于 NodeJS 和 MongoDB 构建的。但是,我选择了这些技术,因为它们是解决我基于文档的问题的正确技术。如果我的数据是像你这样的关系排序系统,我会立刻放弃 Mongo。
</rant>
【讨论】:
感谢您的回复。我不得不说,我认为为这个特定项目选择 mongo 可能是正确的——感觉就像我已经违背了规律。我知道 ref 两次击中数据库 - 这就是我选择嵌入的原因。鉴于数据的使用方式,我不太担心需要在Orders
上进行查询或索引。但是,是的,如果我也决定的话,我会被搞砸的。以上是关于有效的mongodb + mongoose。架构设计的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 mongoose 或 mongodb 查询更改架构内的方案数组内的值。?
使用 mongodb / mongoose 有条件地将 5-20k 文档的输入批次处理成一个包含多达一百万个文档的集合的有效方法是啥?