我是MongoDB的新手,我很难在其中实现解决方案。考虑这样一个例子,我有两个集合:一个是客户集合,一个是销售集合,它们具有这样的设计
Client
==========
id
full name
mobile
gender
region
emp_status
occupation
religion
Sales
===========
id
client_id //this would be a DBRef
trans_date //date time value
products //an array of collections of product sold in the form {product_code, description, units, unit price, amount}
total sales
现在需要为分析查询开发另一个集合,其中可以回答以下问题
- 按性别、地区和emp_status划分的销售分布是怎样的?
- 客户在特定地区最常购买的产品是什么?
我考虑实现一个非常非规范化的集合,以创建一个销售和客户集合属性的扁平和广泛的集合,以便我可以使用map-reduce来进一步回答问题。在RDBMS中,由连接返回的聚合可以回答这些问题,但我不知道如何使Map-Reduce或聚合帮助解决这些问题。
问题:我如何实现map - reduce映射跨2个集合?是否有可能链化MapReduce操作?
问候。
MongoDB不做join - period!
MapReduce总是运行在单个集合上。一个MapReduce作业不能从多个集合中进行选择。聚合也是如此。
当你想做一些数据挖掘时(不是mongodb最擅长的),你可以创建一个包含所有Sales
的非规范化集合,并嵌入相应的Client
对象。您需要编写一个小程序或脚本,遍历所有客户端和
- 查找客户端 的所有
- 将
Client
的相关字段合并到每个文档中 - 将结果文档插入新集合
Sales
文档当您的Client
文档很小并且不经常更改时,您可以考虑将始终嵌入到每个Sales
中。这意味着您将拥有冗余的数据,从经验丰富的RDB老手的角度来看,这看起来非常糟糕。但是请记住,MongoDB不是一个关系数据库,因此您不应该应用所有未反映的RDBMS教条。数据库规范化的"无冗余"规则只有在连接相对便宜且轻松的情况下才可行,而MongoDB并非如此。此外,有时您可能需要冗余来确保数据的持久性。当您想了解按地区销售的历史发展时,您想知道客户购买产品时居住的地区,而不是他们现在居住的地区。当每个Sale
只引用当前Client
文档时,该信息将丢失。当然,您可以使用具有日期范围的单独Address
文档来解决这个问题,但这会使它变得更加复杂。
另一种选择是在每个Client
中嵌入一个Sales
数组。但是,MongoDB不喜欢随时间增长的文档,所以当您的客户端倾向于经常返回时,这可能会导致低于标准的写入性能。