2

在我正在开发的一个应用程序中,一个要求是进行大规模集合交集,大约 10-1,000,000 个项目。我们相交的项目只是 ObjectId 的。

因此,例如有一个 box 文档,并且在 boxes 文档内有一个 item_ids 数组。每个盒子的 item_ids 数组包含 10-1,000,000 个 ObjectId。

这里的最终目标是说,给定 ObjectId 为 4d3dc3898951498107000005 的框 A 和 ObjectId 为 4d3dc3898951498107000002 的框 B,它们有哪些共同的 item_id?

这是我的做法:

db.boxes.distinct("item_ids", {'_id' : {$in : [ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}})

首先只是好奇这是否看起来是一种理智的方法。到目前为止,在我的研究中,似乎 map reduce 是大型交叉路口的常见建议,但不建议用于实时查询。

其次,好奇这在分片环境中会如何表现?mongos 会在它需要的 mongod 上运行大量查询并神奇地聚合我的结果吗?

最后,如果上述内容是理智的,那么这样做是否也是理智的:

db.items.find({'_id' : { $in : db.eval(function() {return db.boxes.distinct("item_ids", {_id:{$in:[ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}}); }) }}) 

这基本上是找到盒子 A 和盒子 B 有哪些共同点,然后在一个服务器端查询中将它们具体化为对象。这似乎也适用于 .limit 和 .skip 以有效地实现数据集的分页。

无论如何,任何反馈都是有价值的,谢谢!

4

1 回答 1

3

我认为您可能需要重新考虑您的架构。如果您在一个数组中有 1,000,000 个 ObjectID,每个 12 字节为 12MB,甚至不计算 BSON 开销,这对于大型数组来说可能很重要*(可能还有 8MB 左右)。在 1.8 中,我们将最大文档大小从 4MB 提高到 16MB,但即使这样也不足以存储您要存储的对象。

*由于历史原因,我们将每个元素的 stingified 索引存储在数组中,当您有 <100 个元素时这很好,但当您需要 6 或 7 位数字时会加起来。

于 2011-01-26T19:56:53.713 回答