find()方法和Node.js的驅動程序遊標
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
MongoClient.connect('mongodb://localhost:27017/crunchbase', function(err, db) {
assert.equal(err, null);
console.log("Successfully connected to MongoDB.");
var query = {
"category_code": "biotech"
};
db.collection('companies').find(query).toArray(function(err, docs) {
assert.equal(err, null);
assert.notEqual(docs.length, 0);
docs.forEach(function(doc) {
console.log(doc.name + " is a " + doc.category_code + " company.");
});
db.close();
});
});
注意,通話.toArray
正在爲獲取整個數據集的應用程序。
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
MongoClient.connect('mongodb://localhost:27017/crunchbase', function(err, db) {
assert.equal(err, null);
console.log("Successfully connected to MongoDB.");
var query = {"category_code": "biotech"};
var cursor = db.collection('companies').find(query);
function(doc) {
cursor.forEach(
console.log(doc.name + " is a " + doc.category_code + " company.");
},
function(err) {
assert.equal(err, null);
return db.close();
}
);
});
注意,光標由find()
返回分配給var cursor
。採用這種方法,我們不是一次性獲取memort中的所有數據並使用數據,而是將數據傳輸到我們的應用程序。 find()
可以立即創建遊標,因爲它實際上並沒有向數據庫發出請求,除非我們嘗試使用它將提供的某些文檔。 cursor
的要點是描述我們的查詢。 cursor.forEach
的第二個參數顯示驅動程序耗盡或發生錯誤時要執行的操作。
在上述代碼的初始版本中,它是toArray()
,它強制數據庫調用。這意味着我們需要所有的文件,並希望他們在array
。
另外,MongoDB
以批處理格式返回數據。下面顯示的圖像,從遊標請求(從應用程序)MongoDB
![MongoDB cursor requests](https://lh3.googleusercontent.com/_utjj5lUN8AMPPf9JCUf3NwP6SoK14g9IrDiglPhNOyLYQq81PaoibVcsDGLxtN1GgBOrUk-_xiobeUcKSUP90crPC7JiflvblQhgRX-d_8noqoBXkQxhDGLRJs8O2LvcdwA4_hoGJSVmFgDUZUkRI-TYG2PKaQMKE171ufX3QFHkKE-jO1gZC06mHAxRLhuDkzip1IFR-Slo-Y6i4hO_bnNGSIMLflu40KZ-waxx0El1D0rNu3JfWFvMkta48SB2a9SGmSZnOD-Vl8A_8B9i7xk4oCaY4TZLq5PKOcgL8z_pCSY2sTqkYACHfl_Itd54Od38fpPAIBu7TWKKAm8hAJfU6QAfuAOiT1khMmzOqvO6zRmEAVlrXybWV26WDtvBumcfmnaZIBUUNUC7MeKP0nim32axhwJQxa_hEs7kmNHjrOzp2k4URp_mFl-XIBNfCGPkjafJkgnw2Tfz4qI8E5p1L29hlgjAmJyZWKvA8Ny5olYK7fe_N_1Sj9mc0hm3vnMnuKaA61pReh8Q2OSLqwJxyYRXhocFaNC6HXiBaqH9s4_VahUeO_xHvdgZWL1u9SGPYiNK2vVSexagjYVKJXnJ3RfJ1g=w668-h230-no)
forEach
比toArray
更好,因爲我們可以處理文檔,因爲他們進來,直到我們到達終點。將其與toArray
對比 - 我們在那裏等待全部要檢索的文件和整個數組已建成。這意味着我們沒有從驅動程序和數據庫系統一起工作將結果批量分發到應用程序的事實中獲得任何優勢。批處理意味着提供內存開銷和執行時間方面的效率。 充分利用它,如果你可以在你的應用。
我覺得你的問題是在你應該問的話題上徘徊。如果你確實收到*「光標找不到」*異常,那麼故障問題將是你實施的代碼。關於遊標「實際是什麼」的更廣泛的討論更多的是「更廣泛的設計問題」,而不是解決特定編程問題的東西,比如本網站的用途,因此*「對遊標過度咆哮,代碼不夠這可能會導致問題「*。就目前而言,你的問題看起來像是在要求一篇論文解釋遊標是什麼。只需顯示一些代碼。 –
問題是,這些例外的發生取決於環境。我們目前不知道,哪個參數(內存,CPU,什麼)是至關重要的參數。所以我對一些**背景感興趣**。我們的代碼看起來像'ds.find(Translation.class).asList()'(ds是Morphia.Datastrore)。 – BairDev
如果您在副本集中運行mongo,則如果您的服務器決定在另一個主節點上,則光標將會丟失。 – froderik