您如何在MongoDB中建立友谊关系?

Sci*_*tes 1 data-modeling mongodb

我知道已经给出了许多建议,建议嵌入对其他用户的引用数组,但是忽略了所有此类答案,就是友谊是一种双向关系,当爱丽丝是鲍勃的朋友时,鲍勃自动是爱丽丝的朋友。我不是模仿追随者。

因此,我不想每次新用户进入系统时都保留两个引用。我需要一个考虑到关系的双向性质的模型。

我当时在考虑友谊的“边缘”集合,其中每个文档都引用了两个用户。想知道有关此的文献是否已经存在。

Phi*_*ipp 5

通常,MongoDB不适合用于建模图形关系。有专门的图形数据库可以胜任此任务。

但是,当您不想在数据库中添加其他数据库技术时,建议您创建一个新集合,frienships并将每个朋友关系建模为带有两个条目的数组的文档,每个条目都有一个有关以下内容的缩写信息:您需要在朋友列表中显示条目的用户之一:

{
    friendship: [
       {
            id:123,
            name: "Bob",
            avatar: "Bob.jpg"
       },
       {
            id:456,
            name: "Alice",
            avatar: "Alice.jpg"
       }
    ]
}
Run Code Online (Sandbox Code Playgroud)

从友谊文档中的用户文档中复制信息的原因是为了避免再次查询用户集合,以获得用于显示用户朋友列表的所有数据。MongoDB 不能执行JOIN 只能对未分片的集合执行JOIN,因此您应避免将特定用例所需的数据分散在多个集合上,即使这意味着您创建了冗余。否则,您需要一个接一个地执行多个查询,这会大大降低应用程序的响应时间。

当您想获取用户123的朋友列表时,您将执行db.friendships.find({"friendship.id", 123})(索引friendship.id将提高性能),然后接收其中Bob是第一个或第二个朋友的文档列表。

然后,您将迭代这些文档并输出不是用户123 的数组条目的简短信息。

或者,您可以使用聚合管道过滤数据库上的Bob条目。使用上面的$ match查询,$ unwind友谊数组,然后$ id匹配id不为123的那些文档。这将是一个折衷方案:您可以节省带宽,但要消耗数据库服务器上的CPU负载。

要查询是否已经存在友谊关系,请使用:

db.friendships.find( { $and: [ 
       { "friendship.id": 123 }, 
       { "friendship.id": 456 } 
    ] } ).count();
Run Code Online (Sandbox Code Playgroud)

  • @DimitrisZorbas您需要优先考虑一致性与性能。在这种特殊情况下,一致性不是那么重要。以一个用户更改其头像为例。是的,需要更新许多很多友谊文档,并且这不是原子操作,因此需要一段时间,直到所有友谊列表都显示新的头像。但这是一项性能无关紧要的操作,可以在后台完成。在网络的所有用户都看到新的头像之前,花费几分钟甚至几小时的时间,用户甚至都不会注意到。 (2认同)