如果您想通過「頁碼」,那麼你幾乎套牢後,你對你的鍵排序結果應用.limit()
和.skip()
方法進行分頁。您可能已經做了一些閱讀,發現它「效率不高」,主要是因爲「跳過」「n」結果以達到某個頁面的成本。
但原理是在你需要它的聲音:
db.collection.find().sort({ "s": -1, "_id": 1 }).skip(<page-1>).limit(<pageSize>)
只要你只需要在你的頁面「前進」有一個更快的替代方案有,也是「分類」結果的工作。
關鍵是要保留對「s」的「最後看到」值的引用,然後一般列出_id
值,直到「s」的值發生變化。所以多帶幾個文件證明,已經被排序用於演示目的:
{ "_id": 1, "s": 3 },
{ "_id": 2, "s": 3 },
{ "_id": 3, "s": 3 },
{ "_id": 4, "s": 2 },
{ "_id": 5, "s": 1 },
{ "_id": 6, "s": 1 },
爲了得到「第一頁」的「兩化」導致你的第一個查詢很簡單:
db.collection.find().sort({ "s": -1, "_id": 1}).limit(2)
而是遵循通過到處理的文件:
var lastVal = null,
lastSeen = [];
db.collection.find().sort({ "s": -1, "_id": 1}).limit(2).forEach(function(doc) {
if (doc.s != lastVal) { // Change when different
lastVal = doc.s;
lastSeen = [];
}
lastSeen.push(doc._id); // Push _id onto array
// do other things like output
})
所以對第一次迭代的lastVal
值將是3
和lastSeen
將包含文件_id
中的數值[1,2]
。 這些東西,你會存儲在像等待下一頁請求的用戶會話數據。
根據您的要求進行設置,那麼您發出的下一個頁面如下:
var lastVal = 3,
lastSeen = [1,2];
db.collection.find({
"_id": { "$nin": lastSeen },
"s": { "$lte": lastVal }
}).sort({ "s": -1, "_id": 1}).limit(2).forEach(function(doc) {
if (doc.s != lastVal) { // Change when different
lastVal = doc.s;
lastSeen = [];
}
lastSeen.push(doc._id); // Push _id onto array
// do other things like output
})
,詢問那的「S」兩個選擇需要從一個值「小於或等於」開始(因爲)的lastVal
記錄,並且「_id」字段不能包含記錄在lastSeen
中的值。
產生的下一個頁面是:
{ "_id": 3, "s": 3 },
{ "_id": 4, "s": 2 },
但現在,如果你遵循的邏輯lastVal
當然2
和lastSeen
現在只有單一的數組元素[4]
。由於下一個查詢只需要將2
作爲較小或相等的值,因此不需要保留先前看到的其他「_id」值,因爲它們不在該選擇內。
,然後處理只是如下操作:
var lastVal = 2,
lastSeen = [2];
db.collection.find({
"_id": { "$nin": lastSeen },
"s": { "$lte": lastVal }
}).sort({ "s": -1, "_id": 1}).limit(2).forEach(function(doc) {
if (doc.s != lastVal) { // Change when different
lastVal = doc.s;
lastSeen = [];
}
lastSeen.push(doc._id); // Push _id onto array
// do other things like output
})
所以按照邏輯的這種模式,你可以在「商店」從你的「previousc網頁」結果發現,這些信息「前進」在搜索結果中很有效率的。
但是,如果您需要跳轉到「第20頁」或類似的操作類型,那麼你堅持.limit()
和.skip()
。這種方式速度較慢,但這取決於你能忍受的。
很好的解決方案,@ blakes-seven你能解釋爲什麼當提取第二頁時,你正在使用lastSeen = [2]而不是[4]? –