Mongo多对多

3
我是一位有用的助手,可以为您翻译以下内容:

我正在尝试建模一个顾客“喜欢”食物的多对多关系。

我预计会得到大量(数百万)这些关系,因此我不希望它们都最终汇集到一个无法扩展的连接表中。

我创建了两个文档集合,

Customers
 - name etc 
 - countOfLoves
 - loves [ ... ]

并且

Foods
 - name etc
 - countOfLoves
 - loves [ ... ]

在每个文档中,都有一个名为“爱好”的子文档集合,代表了不同之间的关系,并且包含一个计数器,可以快速获取总数。
我曾经以为这种方法可以很好地扩展,因为不需要查询拥有数百万行的表格,而只需获取单个文档及其子数组。然而,当客户开始喜欢许多食物(反过来,当一种食物被许多客户所爱时),我遇到了一个问题。
以下是更新客户文档的查询语句,在这种情况下,客户已经喜欢其他7000种食物:
 query: { _id: "354286" } 
update: { $push: { loves: { foodID: "354286", location: [ 55.752197, 37.6156 ] } }, $inc: { countOfLoves: 1 } }
nscanned:1 nupdated:1 keyUpdates:0 locks(micros) w:10135199 10137ms

实际上这里有两个问题:

a) 为什么需要10秒钟 - 是否有关于$push我不知道的东西

b) 是否有更好的Mongo模式可以建模这种关系?

(并且,我猜想 (c) - 我是否过度优化 - 应该只需创建一个loves连接表就可以了吗?)

1个回答

1

我发现一个原因是,如果文档的大小过大而无法放在原位,则会移动到另一个位置,这可能是10秒的原因之一。您可以在此处查看类似的讨论:https://groups.google.com/forum/?fromgroups=#!topic/mongodb-user/FnL0mDWs5w0。解决方案之一是在创建时使用带有虚拟值的数组字段,并使用某种方式来更新它们,而不是添加新的“喜欢”。在这种情况下,您可能需要选择一个名为“Loves”的其他集合,其中对于每个“喜欢”,您将存储客户ID以及他所喜欢的内容。


创建第三个集合的替代方案是允许每个食品和客户有多条记录。在这种情况下,您可以为每个集合设置喜欢的数量限制(例如10),填充该数字,然后在所有插槽都满时移动到新记录。您需要在每个文档中设置一个“已满”标志,该标志将成为您的查找索引的一部分,以便快速插入。 - James Wahlin
这看起来是个不错的选项,但有什么可能的方式可以使它更好地填充呢?你有什么想法吗? - Devesh
1
请查看以下页面,该页面提供有关手动填充的指导:http://docs.mongodb.org/manual/faq/developers/#can-i-manually-pad-documents-to-prevent-moves-during-updates - James Wahlin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接