MongoDB的分析查询

时间:2014-06-30 14:35:52

标签: mongodb join mapreduce analytics

我是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

现在需要为分析查询开发另一个集合,以便回答以下问题

  1. 按性别,地区和emp_status划分的销售额是多少?
  2. 特定地区的客户主要购买哪些产品?
  3. 我考虑实现一个非常规非常化的集合来创建销售和客户端集合的属性的平面和广泛集合,以便我可以使用map-reduce来进一步回答问题。 在RDBMS中,由联接返回的聚合将回答这些问题,但我不知道如何使Map-Reduce或Agregation帮助。

    问题: 如何实现Map-Reduce以映射2个集合? 是否可以链接MapReduce操作?

    问候。

1 个答案:

答案 0 :(得分:2)

MongoDB不执行JOIN - 期间!

MapReduce始终在单个集合上运行。您不能拥有一个从多个集合中选择的MapReduce作业。这同样适用于聚合。

当您想要进行一些数据挖掘(而不是MongoDB最强的套装)时,您可以创建一个所有Sales的非规范化集合,并嵌入相应的Client对象。您将不得不编写一个迭代所有客户端的小程序或脚本

  1. 查找clinet的所有Sales个文档
  2. Client中的相关字段合并到每个文档
  3. 将生成的文档插入新集合
  4. 当您的Client文档较小而且不经常更改时,您可能会考虑始终将其嵌入到每个Sales中。这意味着你将拥有多余的数据,从经验丰富的RDB老手的角度来看,这看起来非常邪恶。但请记住,MongoDB不是关系数据库,因此您不应该应用未反射的所有RDBMS教条。只有当JOIN相对便宜且无痛时,数据库规范化的“无冗余”规则才是可行的,而MongoDB则不然。此外,有时您可能需要冗余来确保数据持久性。如果您想了解按地区划分的销售历史发展情况,您想知道客户在购买产品时居住的地区,而不是他们现在居住的地方。当每个Sale仅引用当前的Client文档时,该信息将丢失。当然,您可以使用具有日期范围的单独Address文档解决此问题,但这会使其更加复杂。

    另一种选择是在每个Sales中嵌入一个Client数组。但是,MongoDB不喜欢随时间增长的文档,因此当您的客户经常返回时,这可能会导致写入性能低于标准。