【发布时间】:2011-03-16 20:48:36
【问题描述】:
在 MongoDB 中传递给 $in 查询的最大参数数是多少?
【问题讨论】:
-
我在某处读到它是 1 000 000。
-
实际计算见下文。
标签: mongodb
在 MongoDB 中传递给 $in 查询的最大参数数是多少?
【问题讨论】:
标签: mongodb
查询本身就是一个文档。 MongoDB 将文档大小(从 2.4.0+ 版开始)限制为 16 MB。
真的,你对 find 所做的是:
db.collectionName.find(queryDoc)
'queryDoc' 类似于:
{ 'fieldOne' : { $in : [ 1, 2, 3, 4] } }
要找到可以传递给 $in 查询的最大值数,请使用 bsonsize 命令:
mongos> Object.bsonsize([1])
16
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4] } })
74
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5] } })
85
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6] } })
96
因此,您可以看到每个额外的整数大小为 11 个字节。不是 11 位,11 字节。这是由于 BSON 在内部将数字存储为每个至少 64 位的方式,加上包装器。这可以通过以下方式轻松看出:
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 69000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 6900000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 69000000000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 69000000000000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 6900000000000000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 690000000000000000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 69000000000000000000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 6900000000000000000000] } })
107
mongos> Object.bsonsize({ 'fieldOne' : { $in : [ 1, 2, 3, 4, 5, 6, 69000000000000000000000000] } })
107
所以,无论单个数字的大小,它都是相同的 bsonsize。
关于问题本身:该查询文档有多大?
在 pymongo 中,通过 mongos javascript 提示将这些添加到带有 $in 子句的单字段查询中,无论如何,对于 $in 查询的最大大小,都产生相同的附加事实:
mongos> Object.bsonsize({ 'a' : { '$in' : [1] }})
34
mongos> Object.bsonsize({ '' : { '$in' : [1] }})
33
mongos> Object.bsonsize({ '' : { '$in' : [] }})
22
所以,假设你有一个单字节的字段名(实际上是最小值),你的最大值是:
mongos> 16*1024*1024
16777216
mongos> (16*1024*1024) - 22 - 1
16777193
mongos> ((16*1024*1024) - 22 -1) / 11
1525199.3636363635
答案:1,525,198(这是 150 万。相当大。)
【讨论】:
看起来没有限制。
我做了一个小测试。
1) 集合 A 有 - 100 万个简单 JSON 对象 {id:,name:}
2) 在集合 B 中,我加载了集合 A 的引用 ID,直到出现以下异常。我可以插入最大 450k 的引用计数。
Exception in thread "main" com.mongodb.MongoInternalException: DBObject of size 18388885 is over Max BSON size 16777216
3) 我可以发送 450k 这些 id 作为 $in[id1...id450000] 并从集合 A 中的 100 万个对象中提取 450k id 的整个列表。
哇!这对我的应用程序来说绰绰有余:D。 MongoDB真的很酷。
【讨论】:
我认为限制只是由 BSONDocument 的大小决定。定义查询时,您可以继续向 $in 子句添加值,直到超过最大文档大小。因此,您可以在子句中包含多少值取决于每个值有多大(每个值的大小越小,您可以在 $in 子句中包含的值越多)。
就性能而言,根据我的发现,$in 子句中的值数量有一个“最佳位置”。在这个相关问题中查看我的答案:Is it OK to query a MongoDB multiple times per request?
即平衡 $in 子句中的值数量与发送的查询数量。我正在写一篇博文,试图深入了解更多细节。
【讨论】:
我正在寻找一个答案来确认我可以在 IN 子句中传递多少个 UUID。所以发布结果以防万一它帮助别人。
我尝试像这样传递 500 UUID:
Object.bsonsize({ 'fieldOne' : { $in : [
"3bd209e1-41c9-4ad2-a62c-bbe3d2ae490a",
"3bd209e1-41c9-4ad2-a62c-bbe3d2ae490a",
"3bd209e1-41c9-4ad2-a62c-bbe3d2ae490a".
..
..] } })
结果是:23518
【讨论】: