我有一个关于map / reduce的问题,以及它是否适合我正在努力完成的任务。我还处于设计阶段,所以如果需要,我可以改变数据的结构。
想象一下,我有两个这样的文件:
{ "_id" : ObjectId( "50231b4f8be6e5f1f2e7e24g" ),
"customer" : "50bac36bb4e54678170002e6",
"display" : "Motorola Canopy 100",
"description" : "a radio" }
{ "_id" : ObjectId( "50232fac8be6e4f1f2e7e259" ),
"display" : "Motorola POE",
"description" : "a power injector",
"device" : "50231b4f8be6e4f1f2e7e24g" }
在一个文档上,有一个客户ID引用(“customer”:“50bac36bb4e54678170002e6”),另一个文档中有一个设备ID引用(“device”:“50231b4f8be6e4f1f2e7e24g”)。这两个文件都代表某种设备。该设备将与客户相关(也称为,分配)或与另一设备相关。例如,客户将获得一台收音机,它将被分配,但电源注入器将分配给收音机本身,而不是客户。我这样做了,所以我可以更好地理解设备之间的操作依赖性。保持这种分层关联模式很有用,如果可能的话我想保留它。
我目前运行一系列查询,首先查找所有设备,然后对于找到的每个设备,运行另一个查询以查找相关设备。这是一个递归操作,可以与任何给定设备的关联一样深。
我很想知道这个问题是否适合map / reduce操作。我应该坚持使用我当前的递归操作还是这是一个很好/完美适合map / reduce?
进一步澄清评论中提出的问题:
答案 0 :(得分:3)
MapReduce最适用于没有依赖关系的文档。如果您的数据结构只是一个有向无环图(DAG),其中每个客户都是根节点,并且每个设备可能有多个父节点。由于依赖关系,Map / Reduce不适合大多数DAG操作。
但是,由于您的数据是树状的(没有多父母),您可以add an array of ancestors as in the MongoDB docs example。在这种情况下,MR可能非常适合某些操作。
如果我理解你的查询策略,我担心在每个递归级别的内部循环中执行大量查询操作的效率。为了帮助实现这一点,理想情况下,“device”应该是ObjectId类型而不是字符串,并且应该对其进行索引。索引的替代方法也可以是store the children ObjectId's as child references per this MongoDB docs example。在任何一种情况下,为每个递归级别运行MR或“$ group”聚合操作都可能有所帮助,但我怀疑在大多数情况下它只会将计算从DB客户端转移到DB服务器。
答案 1 :(得分:1)
我不认为map / reduce在这里是一个很好的解决方案,因为数据是相互依赖的,这使得并发无效。或者,您可以使用dbRef嵌入相关设备,以便可以直接从相关设备文档中访问它。