天天看點

MongoDB - 遊标

MongoDB有一個很重要的特性就是遊标Cursor,當然我們項目中也在使用,是以還是需要好好的進行研究一番。遊标可以了解為指針,當去完一個則會将指針指向下一個。若是像我們項目,每天需要同步一遍全部的資料,則使用指正應該是非常合适的。但是它也伴随着很多問題需要注意。

1、遊标

    var cursor = db.user.find({}); # 定義遊标

    cursor.hasNext();                  # 查詢是否還有下一個

    cursor.next();                         # 擷取遊标的下一個元素

MongoDB - 遊标

    遊标擷取資料過程:遊标建立後,若是使用用戶端使用next()或者hasNext()方法,則用戶端會向服務端一次性擷取100條或者4M資料(哪個小擷取哪個),則程式在使用完之後則可以直接在用戶端進行或者後面的資料,若用戶端的資料使用完的情況下則會使用getMore調用服務端或者後面的指針資料,知道遊标耗盡或者擷取了所有的結果。

2、遊标使用注意事項

    1)、遊标執行過程中,修改資料可能會影響遊标傳回的結果

    由于Mongo存儲資料的問題,當執行修改文檔時,文檔由于大小的變化則修改後不一定會放到原來的位置。這也是Mongo在執行一段時間後需要整理空間碎片的原因。當然文檔位置發生了變化之後(放到了其他的位置),遊标在建立完之後就像是一個快照,當遊标擷取下一次的資料的時候,則不能全部擷取所有的資料。

    這個時候需要使用快照(snapshot)進行查詢,則會查詢預設索引_id的資料,但是性能會比較差,如下:

    var cursor = db.user.find({}).snapshot();  # 後面的執行方式不變

    2)、遊标的生命周期

    遊标需要知道用戶端和服務端都在做什麼,最重要的是服務端需要維護建立的遊标,當遊标建立的過多,或者沒有及時的進行釋放,可能會增加伺服器的資源壓力。

    遊标在被調用完,或者驅動程式發送銷毀指令,或者伺服器逾時機制(預設在10分鐘之後沒有使用完也會進行銷毀);若需要延遲銷毀則需要immortal機制,驅動程式都有進行實作。使用Spring的MongoTemplate進行遊标查詢,将在後面進行補充。