【问题标题】:What is the most efficient way to query multiple collections in MongoDB?在 MongoDB 中查询多个集合的最有效方法是什么?
【发布时间】:2013-11-21 22:00:58
【问题描述】:

我在 MongoDB 中有 3 个集合,它们的架构无法更改。一些查询需要访问 3 个集合。

我知道我需要多个查询来执行此操作,但我不确定执行此操作的最有效方法是什么。下面的例子被简化了:

我的数据包含一个“用户”集合,它充当其他两个集合的逻辑父级。另外两个集合是“DVD”和“CD”。一个用户可以拥有多张 CD 或 DVD

User Document 
id : "jim",
location : "sweden"

CD Document
name : "White Album",
owner : "jim"

DVD Document
name : "Fargo",
owner : "jim"

现在,我目前采取的方法如下。如果我想取回瑞典用户的所有 CD 和 DVD。

第 1 步

Get all users in Sweden and return a cursor

第 2 步

Iterate through the each user in the cursor and perform a lookup on both the DVD and CD collections to see if the users id matches the owner field

第 3 步

If it does add the user to an array to be returned

这种方法需要 2 个额外的查询,对我来说似乎效率很低。有没有更有效的方法来做到这一点?

【问题讨论】:

  • 为什么 CD 和 DVD 不在同一个集合中?
  • @Phillip 这只是一个简化的例子

标签: mongodb mongodb-query


【解决方案1】:

您可以对查询进行一些改进,如下所示。

  • 选择用户时,仅返回 id 字段。

db.user.find({location:"sweden"},{id:1})

  • 创建一个包含用户名的字符串列表并使用 $in 查询传递这些列表。对 cd 和 dvd 集合运行 $in 查询,如下所示:
db.cd.find({owner : {$in : ["jim", "tom", ...]}})
db.dvd.find({owner : {$in : ["jim", "tom", ...]}})

还可以在集合上添加索引以提高查询性能。

【讨论】:

  • 我之前尝试过这种方法,但担心用户集合可能包含大量用户。因此,正在使用的阵列可能包含 100 万以上的用户。这种大小的数组会使查询失败吗?
  • AFAIK,传递给 $in 运算符的数组大小没有限制。这里唯一的限制是 Bson 文档大小 (16 mb)。如果您的数组大小为 1M,那么您可以通过将 100K 传递给 $in 查询来运行相同的查询 10 次。这仍然比运行 1M 查询要好。
  • 嗯投影不会使查询更有效率,它只会缩小返回的数据量。另外,用户名的字符串列表是什么意思?它是如何工作的?
  • 我知道投影不会使查询更高效,但在这里我尝试提及编写查询时的最佳实践。另外,通过字符串列表,我的意思是创建用户名列表并将这些列表作为参数发送到 $in 中。这对查询没有任何改进。我只是尝试解释如何编写qurey。
【解决方案2】:

它并不像听起来那么低效。

您很可能会想到 SQL 技术,即每次查询时都会生成一个结果集,然后将其缓存在磁盘或内存中。

MongoDB 直接从每个游标批次的数据文件中流式传输,这意味着它的数据是来自数据库的“实时”数据,这与结果集不同。这也意味着 ping 奇数查询也会占用大量资源。

正如您所说,一个选项是带回所有用户,并且每次迭代判断他们是否应该显示,因为他们有相关记录。这可以均匀分布停止超载的游标,但是,服务器上仍然存在游标超载的可能性。

另一种选择是遍历瑞典的所有用户并返回一个巨大的user_id 数组,用于查询 CD 和 DVD 集合。然后,您将在您的应用程序中匹配它们并根据需要返回。

但是,具体如何解决这个问题取决于您的场景以及您拥有多少数据。

【讨论】:

    【解决方案3】:

    如果您无法更改架构,并且 你想知道有多少来自瑞典的用户拥有一张 CD 或 DVD,那么我认为这是最小的方法:

    • users_ids * = 从 DVD 和 CD 收藏中获取所有 users_id。 获取所有在 * users_ids * 中有自己的 id 并且来自瑞典的用户。

    那么您只有 2 个查询,但如果您的 DVD 和 CD 收藏足够大,这可能不会比您的方法快,即使此方法仅使用 2 个查询。

    请记住,较少的查询并不一定意味着更快。

    对不起英文;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 2015-04-08
      • 2017-03-16
      • 2012-10-14
      • 2022-01-22
      • 1970-01-01
      相关资源
      最近更新 更多