在 MongoDB 中,getMore 函数的触发时机
MongoDB 在对返回大量结果的 find() 或 aggregate() 进行操作时,并不会一次性获取所有结果,而是将其分为几个部分进行获取。
使用getMore的条件如下所述。
-
- 初回は101ドキュメントを取得する
- 未取得のドキュメントがある場合は getMore を使って1回につき16MBを超えない範囲でドキュメントを取得する
下面的例子中,获取101个文档时没有使用getMore命令,但是当要获取102个文档时,会使用到getMore命令。(这个功能应该是在MongoDB 3.4版本之后添加的)
参考:https://docs.mongodb.com/manual/tutorial/iterate-a-cursor/#cursor-batches
irb(main):001:0> Item.limit(101).map(&:name); nil
MONGODB | [7] localhost:28001 #1 | sandbox.find | STARTED | {"find"=>"items", "filter"=>{}, "limit"=>101, "lsid"=>{"id"=><BSON::Binary:0x70306682318860 type=uuid data=0xf2b72d35df7c417a...>}}
MONGODB | [7] localhost:28001 | sandbox.find | SUCCEEDED | 0.002s
=> nil
irb(main):002:0> Item.limit(102).map(&:name); nil
MONGODB | [8] localhost:28001 #1 | sandbox.find | STARTED | {"find"=>"items", "filter"=>{}, "limit"=>102, "lsid"=>{"id"=><BSON::Binary:0x70306682318860 type=uuid data=0xf2b72d35df7c417a...>}}
MONGODB | [8] localhost:28001 | sandbox.find | SUCCEEDED | 0.003s
MONGODB | [9] localhost:28001 #1 | sandbox.getMore | STARTED | {"getMore"=>#<BSON::Int64:0x00007fe3196c0f30 @value=8225986221740535645>, "collection"=>"items", "lsid"=>{"id"=><BSON::Binary:0x70306682318860 type=uuid data=0xf2b72d35df7c417a...>}}
MONGODB | [9] localhost:28001 | sandbox.getMore | SUCCEEDED | 0.002s
=> nil
顺便说一下,我调查了getMore函数第二次运行的时机,发现在获取了92914个文档后,第二次运行开始执行。
当然,这个数字本身没有意义,因为它取决于每个文档的大小。
irb(main):043:0> Item.limit(92913).map(&:name); nil
MONGODB | [94] localhost:28001 #3 | sandbox.find | STARTED | {"find"=>"items", "filter"=>{}, "limit"=>92913, "lsid"=>{"id"=><BSON::Binary:0x70306433028540 type=uuid data=0x085ec2a138c44df1...>}}
MONGODB | [94] localhost:28001 | sandbox.find | SUCCEEDED | 0.002s
MONGODB | [95] localhost:28001 #3 | sandbox.getMore | STARTED | {"getMore"=>#<BSON::Int64:0x00007fe33960dc58 @value=5867813388408376440>, "collection"=>"items", "lsid"=>{"id"=><BSON::Binary:0x70306433028540 type=uuid data=0x085ec2a138c44df1...>}}
MONGODB | [95] localhost:28001 | sandbox.getMore | SUCCEEDED | 0.621s
=> nil
irb(main):044:0> Item.limit(92914).map(&:name); nil
MONGODB | [96] localhost:28001 #3 | sandbox.find | STARTED | {"find"=>"items", "filter"=>{}, "limit"=>92914, "lsid"=>{"id"=><BSON::Binary:0x70306433028540 type=uuid data=0x085ec2a138c44df1...>}}
MONGODB | [96] localhost:28001 | sandbox.find | SUCCEEDED | 0.002s
MONGODB | [97] localhost:28001 #3 | sandbox.getMore | STARTED | {"getMore"=>#<BSON::Int64:0x00007fe2fb922dc8 @value=2566893090831268646>, "collection"=>"items", "lsid"=>{"id"=><BSON::Binary:0x70306433028540 type=uuid data=0x085ec2a138c44df1...>}}
MONGODB | [97] localhost:28001 | sandbox.getMore | SUCCEEDED | 0.533s
MONGODB | [98] localhost:28001 #3 | sandbox.getMore | STARTED | {"getMore"=>#<BSON::Int64:0x00007fe339546518 @value=2566893090831268646>, "collection"=>"items", "lsid"=>{"id"=><BSON::Binary:0x70306433028540 type=uuid data=0x085ec2a138c44df1...>}}
MONGODB | [98] localhost:28001 | sandbox.getMore | SUCCEEDED | 0.002s
=> nil
用于验证的文件如下所示。
num 是一个数字(从第一个开始递增),name 是以 item_* 的形式并在末尾带有相同数字 num(整数),然后将一个随机的100字节字符串存储在 description 中。
irb(main):045:0> Item.first
MONGODB | [99] localhost:28001 #3 | sandbox.find | STARTED | {"find"=>"items", "filter"=>{}, "sort"=>{"_id"=>1}, "limit"=>1, "singleBatch"=>true, "lsid"=>{"id"=><BSON::Binary:0x70306433028540 type=uuid data=0x085ec2a138c44df1...>}}
MONGODB | [99] localhost:28001 | sandbox.find | SUCCEEDED | 0.002s
=> #<Item _id: 5e38e59f4bc718a1495d8e4d, created_at: nil, updated_at: nil, num: 1.0, name: "item_1", description: "lbregl1u4pkk95yn2qzg22988jjlotgfendf41hdfuw68gg4f7dbos8tvf1qxcq2qpjvzqll7sl47cwsdt6y7hdewmz35wbu0174">