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

时间:2015-06-08 07:53:39

标签: mongodb data-modeling

我知道已经给出了许多答案,建议将一系列引用嵌入到其他用户中,但是这种疏忽的所有答案都是友谊是一种双向关系,当爱丽丝是鲍勃的时候朋友,鲍勃自动成为爱丽丝的朋友。我没有为粉丝建模。

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

我在想一个友谊和边缘的集合'其中每个文档都包含对两个用户的引用。想知道有关这方面的文献是否已经存在。

1 个答案:

答案 0 :(得分:4)

MongoDB通常不适合建模图关系。有专门的图形数据库,擅长这项任务。

但是,当您不想添加其他数据库技术时,我建议创建一个新的集合frienships并将每个friend-relation建模为一个包含两个条目数组的文档,每个条目都是它们是一个对象,其中包含您需要在朋友列表中显示条目的其中一个用户的缩写信息:

{
    friendship: [
       {
            id:123,
            name: "Bob",
            avatar: "Bob.jpg"
       },
       {
            id:456,
            name: "Alice",
            avatar: "Alice.jpg"
       }
    ]
}

在友谊文档中复制来自用户文档的信息的原因是为了避免对用户集合的第二次查询以获得用于显示用户朋友列表的所有数据。 MongoDB 无法执行JOIN can only perform JOINs on unsharded collections,因此您应避免在多个集合中传播特定用例所需的数据,即使这意味着您创建了冗余。否则,您需要一个接一个地执行多个查询,这会显着减慢应用程序的响应时间。

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

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

或者,您可以使用聚合管道过滤掉数据库上的Bob条目。使用上面的$ match查询,$ unwind the friendship-array然后$匹配id不是123的那些文件。这将是一个权衡:你节省带宽,代价是数据库服务器上的CPU负载。

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

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