MongoDB有一个很重要的特性就是游标Cursor,当然我们项目中也在使用,所以还是需要好好的进行研究一番。游标可以理解为指针,当去完一个则会将指针指向下一个。若是像我们项目,每天需要同步一遍全部的数据,则使用指正应该是非常合适的。但是它也伴随着很多问题需要注意。
1、游标
var cursor = db.user.find({}); # 定义游标
cursor.hasNext(); # 查询是否还有下一个
cursor.next(); # 获取游标的下一个元素
游标获取数据过程:游标创建后,若是使用客户端使用next()或者hasNext()方法,则客户端会向服务端一次性获取100条或者4M数据(哪个小获取哪个),则程序在使用完之后则可以直接在客户端进行或者后面的数据,若客户端的数据使用完的情况下则会使用getMore调用服务端或者后面的指针数据,知道游标耗尽或者获取了所有的结果。
2、游标使用注意事项
1)、游标执行过程中,修改数据可能会影响游标返回的结果
由于Mongo存储数据的问题,当执行修改文档时,文档由于大小的变化则修改后不一定会放到原来的位置。这也是Mongo在执行一段时间后需要整理空间碎片的原因。当然文档位置发生了变化之后(放到了其他的位置),游标在创建完之后就像是一个快照,当游标获取下一次的数据的时候,则不能全部获取所有的数据。
这个时候需要使用快照(snapshot)进行查询,则会查询默认索引_id的数据,但是性能会比较差,如下:
var cursor = db.user.find({}).snapshot(); # 后面的执行方式不变
2)、游标的生命周期
游标需要知道客户端和服务端都在做什么,最重要的是服务端需要维护创建的游标,当游标创建的过多,或者没有及时的进行释放,可能会增加服务器的资源压力。
游标在被调用完,或者驱动程序发送销毁命令,或者服务器超时机制(默认在10分钟之后没有使用完也会进行销毁);若需要延迟销毁则需要immortal机制,驱动程序都有进行实现。使用Spring的MongoTemplate进行游标查询,将在后面进行补充。