MongoDB 在没有 join 的情况下,要如何解决这样的类似 join 的功能

ryan · 2013年06月24日 · 最后由 Ryan 回复于 2013年06月25日 · 4441 次阅读

工作中遇到这样一个问题,现在有两个 collection,一个 container,一个 object,各自都有各自的属性,而且不是小数据模型,container 可有多个 object,object 归属于一个 container。

现在需求要对所有的 container 和 object,依据某个搜索条件进行搜索,同时列出所有符合条件的 container 和 object。并支持分页。因此,在数据量庞大的条件下,无法预知这分页后的数据该如何分配给 container 和 object。

由于 mongodb 不支持 join,这样操作变得复杂。同时两者都不是小数据模型。如果改用内嵌数据模型似乎也不合适,而且两个数据模型都放进一个 collection 中会让这个 collection 变成原来的至少两倍。

所以,是不是有什么好的办法来解决这样的问题呢?

假设分页大小 10 1,先查找符合条件的 container, pagenate 后,得到 container_ids(count = 10 的 array) cs = Container.where({conditions}).page(page).per(10) container_ids = cs.map(&:id) 2,os = Object.where(:container_id.in => container_ids, {other conditions}).group_by(:container_id), 得到一个 count = 10 的 hash 3,比如你要 list 出来的操作 list = cs.map{|x| [x, os[x.id]]}

#1 楼 @zhangrentian 你这个操作是希望通过先依据小数据量的 container 来减少 object 的检索数量是么?但是这里其实不是这样的,如同你代码中所写的先依据 container,那那些不包含在这些已经搜索出来的 container 中却又符合条件的 object,岂不是被忽略掉了?这里有个很大的问题就是虽然 container 和 object 是有关联的,但是面对这样的检索需求,这样的关联,毫无作用。

之前理解错了 毫无作用是不可能的,数据量大就必然要分页,要分页就得排序,要排序就得有 sort key,这个 sort key 必须依赖这个关联 这个问题看看 mongo 的 map reduce 吧

#3 楼 @zhangrentian 你的意思是,map reduce 对这个问题可有效?之前我们有想过用 mongo 的 map reduce,但一直以为他对大数据量的计算有效,而这个是个基本无计算的过程,就是个 retrieve 的过程。。不知道是否可行。

#6 楼 @zhangrentian 文章我看了。我觉得他和我的需求可能还是不同的。我这里的需求是一个并集,也就是满足搜索字段的 container 和 object,而不是满足搜索字段的某一个集合和与此集合中每个元素相关联的另一个集合。

不是的,他是相当于建了一个新表,新生成的表可以非常灵活,最坏情况是你把结果都 join 成一个新表,然后用 or 来得到你的结果。 http://mongoid.org/en/mongoid/docs/querying.html#map_reduce (这里不要先筛选结果,直接 mapreduce 就是 FULL OUTER JOIN 了) 你也可以优化,比如生成的表(假设 out 为 merge)尽量减少字段 但是这个方法确实也不是很好的方法,毕竟数据量太大的话,会感觉浪费空间。不讨论重新设计系统和存储的话,感觉也没有其他好方法

#8 楼 @zhangrentian 原来是这样的。主要是,我看到你给我的文章里,他的 fetch 是依赖关联的,我跟我们经理说其实这里没关联的。所以觉得很奇怪。。。不过我也有想到用临时表,你这个对 map reduce 的解释似乎正好复合我的想法了。不过貌似现在决定改数据结构了。。。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号