MongoDB中传递给$ in查询的参数的最大数量是多少?


73

MongoDB中传递给$ in查询的参数的最大数量是多少?


我在某处读到它是1000000。–
罗马

1
参见下面的实际计算以及所示的功。
凯文·赖斯

Answers:


107

查询本身是一个文档。MongoDB将文档大小(从2.4.0+版本开始)限制为16 MB。

确实,您正在执行的查找操作是:

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都是相同的。

关于问题本身:该查询文件有多大?

通过mongos javascript提示符在pymongo中使用$ in子句将这些字段加到一个字段查询中,无论如何,对于$ in查询的最大大小,它们都具有相同的加法事实:

mongos> Object.bsonsize({ 'a' : { '$in' : [1] }})
34
mongos> Object.bsonsize({ '' : { '$in' : [1] }})
33
mongos> Object.bsonsize({ '' : { '$in' : [] }})
22
  • 查询文档本身为22个字节;
  • 字段名称的每个字节都添加一个字节。
  • 添加到$ in子句中的每个数字都会增加11个字节。

因此,假设您有一个一字节的字段名(实际上是最小值),则最大值为:

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万。这是非常大的数字。)


34

看起来没有限制。

我做了一个小测试。

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真的很棒。


7

我认为限制仅由BSONDocument的大小确定。定义查询时,可以继续将值添加到$ in子句中,直到超过最大文档大小为止。因此,子句中可以有多少个值取决于每个值的大小(每个值的大小越小,您可以在$ in子句中包含的值越多)。

在性能方面,从我发现的情况来看,$ in子句中的值数量有一个“最佳点”。请参阅以下相关问题的答案:每个请求可以多次查询MongoDB吗?

即平衡$ in子句中的值数量与发送的查询数量。我正在撰写有关该主题的博客文章,以尝试深入探讨更多细节。


0

我一直在寻找答案,以确认我可以在IN子句中传递多少UUID。因此,发布结果以防万一对其他人有帮助。

我试图像这样传递500 UUID:

 Object.bsonsize({ 'fieldOne' : { $in : [ 
    "3bd209e1-41c9-4ad2-a62c-bbe3d2ae490a",
    "3bd209e1-41c9-4ad2-a62c-bbe3d2ae490a",
    "3bd209e1-41c9-4ad2-a62c-bbe3d2ae490a".
     ..
     ..] } })

结果是:23518

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.