我们需要能够在用户的朋友和朋友的朋友之间快速执行查询。这在关系数据库中相对简单,但我有点坚持在MongoDB中完成它的最佳方法。我们将用户朋友的用户ID存储在用户文档中的数组中,因此显而易见的解决方案是:
虽然直截了当,但与我们在关系数据库中的连接所做的相比,这看起来像是大量的来回。有没有更有效的方法在MongoDB中执行此操作,或者这是一个最适合RDBMS的问题?
答案 0 :(得分:13)
我最近在MongoDB SV会议上向Eliot Horowitz提出了同样的问题。他说他构建它的方式是将每个用户朋友存储为每个用户的嵌入文档。例如,结构可能如下所示:
{
_id : ObjectId("4e77bb3b8a3e000000004f7a"),
username : "alex",
friends : ["283956723823626626aa", "226567377578888888as", "8738783888aas88a8a88" ]
}
然后你可以在user.friends
上有一个索引http://www.mongodb.org/display/DOCS/Indexes#Indexes-IndexingArrayElements
“当索引键字段的文档存储值是数组时,MongoDB会索引数组的每个元素。有关详细信息,请参阅”多键“页面。”
所以我可以找到所有“亚历克斯”的朋友:
db.user.find({'friends':'4e77bb3b8a3e000000004f7a'});
答案 1 :(得分:7)
与我们在关系数据库中的连接相比,这看起来像是一个大量的来回
这一切都非常相对。你提取“朋友的朋友”的基本假设是正确的,它是一些跳跃和几个记忆中的“区别”。
然而,从“完成工作总量”的原始角度来看,这与您使用SQL的方式没有太大差别。是的,它是一个相对简单的SQL查询,但服务器本身仍然必须完成相同数量的工作,提供或占用一些网络流量。
在MongoDB中有更有效的方法吗,或者这是一个最适合RDBMS的问题?
MongoDB有更好的方法吗?可能不是。但是在SQL中进行“自联接”并不容易跨多个服务器进行扩展。实际上,尝试跨多个服务器执行此操作基本上会转换为与MongoDB进程类似的过程。
从技术上讲,这是一个图形数据库最好的工作,既不是MongoDB也不是RDBMS。
对于图表数据库,您可以查看Trinity for .NET或NEO4J。
答案 2 :(得分:2)
我认为这是由RDBMS(限制图形DB)更好地处理的事情,因为您显然需要执行“连接”操作。虽然RDBMS可能以相同的方式实现它,但它可以更有效地实现连接,并且比MongoDB更有效地分发信息。
话虽如此,如果你有一个庞大的数据库节点集群和大量用户,那么以原子方式执行“连接”查询的开销可能会成本太高。
如果您不担心查询的一致性和原子性,并且您想要的是阻止应用程序和数据库之间的来回,您可以编写一个JavaScript函数来执行整个查询MongoDB,或使用MapReduce操作进行更有效的分布式查询。