आप जिस अवधारणा के बारे में बात कर रहे हैं उसे "फॉरवर्ड पेजिंग" कहा जा सकता है। इसका एक अच्छा कारण .skip()
. का उपयोग करने के विपरीत है और .limit()
संशोधक इसका उपयोग पिछले पृष्ठ पर "वापस जाने" या वास्तव में किसी विशिष्ट पृष्ठ पर "छोड़ने" के लिए नहीं किया जा सकता है। कम से कम "देखे गए" या "खोजे गए" पृष्ठों को संग्रहीत करने के लिए बहुत अधिक प्रयास के साथ नहीं, इसलिए यदि उस प्रकार का "पृष्ठ के लिंक" पेजिंग वही है जो आप चाहते हैं, तो आप .skip()
और .limit()
प्रदर्शन कमियों के बावजूद दृष्टिकोण।
यदि आपके लिए केवल "आगे बढ़ना" एक व्यवहार्य विकल्प है, तो यहां मूल अवधारणा है:
db.junk.find().limit(3)
{ "_id" : ObjectId("54c03f0c2f63310180151877"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("54c03f0c2f63310180151878"), "a" : 4, "b" : 4 }
{ "_id" : ObjectId("54c03f0c2f63310180151879"), "a" : 10, "b" : 10 }
बेशक यह आपका पहला पेज है जिसमें 3 आइटम की सीमा है। उस पर विचार करें कि अब कोड कर्सर को पुनरावृत्त कर रहा है:
var lastSeen = null;
var cursor = db.junk.find().limit(3);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if (!cursor.hasNext())
lastSeen = doc._id;
}
ताकि कर्सर को पुनरावृत्त किया जा सके और कुछ किया जा सके, और जब यह सच हो कि कर्सर में अंतिम आइटम पहुंच गया है तो आप lastSeen
स्टोर करते हैं वर्तमान के लिए मान _id
:
ObjectId("54c03f0c2f63310180151879")
अपने बाद के पुनरावृत्तियों में आप बस उस _id
. को फ़ीड करें मूल्य जो आप क्वेरी में रखते हैं (सत्र में या जो कुछ भी):
var cursor = db.junk.find({ "_id": { "$gt": lastSeen } }).limit(3);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if (!cursor.hasNext())
lastSeen = doc._id;
}
{ "_id" : ObjectId("54c03f0c2f6331018015187a"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("54c03f0c2f6331018015187b"), "a" : 6, "b" : 6 }
{ "_id" : ObjectId("54c03f0c2f6331018015187c"), "a" : 7, "b" : 7 }
और प्रक्रिया बार-बार दोहराई जाती है जब तक कि कोई और परिणाम प्राप्त नहीं किया जा सकता।
_id
. जैसे प्राकृतिक आदेश के लिए यह मूल प्रक्रिया है . किसी और चीज़ के लिए यह थोड़ा और जटिल हो जाता है। निम्नलिखित पर विचार करें:
{ "_id": 4, "rank": 3 }
{ "_id": 8, "rank": 3 }
{ "_id": 1, "rank": 3 }
{ "_id": 3, "rank": 2 }
रैंक द्वारा क्रमबद्ध दो पृष्ठों में विभाजित करने के लिए आपको अनिवार्य रूप से यह जानने की आवश्यकता है कि आपने "पहले ही देखा है" और उन परिणामों को बाहर कर दें। तो पहला पेज देख रहे हैं:
var lastSeen = null;
var seenIds = [];
var cursor = db.junk.find().sort({ "rank": -1 }).limit(2);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if ( lastSeen != null && doc.rank != lastSeen )
seenIds = [];
seenIds.push(doc._id);
if (!cursor.hasNext() || lastSeen == null)
lastSeen = doc.rank;
}
{ "_id": 4, "rank": 3 }
{ "_id": 8, "rank": 3 }
अगले पुनरावृत्ति पर आप अंतिम सीन "रैंक" स्कोर से कम या बराबर होना चाहते हैं, लेकिन उन दस्तावेज़ों को भी छोड़कर जो पहले से ही देखे गए हैं। आप इसे $nin
. के साथ करते हैं ऑपरेटर:
var cursor = db.junk.find(
{ "_id": { "$nin": seenIds }, "rank": "$lte": lastSeen }
).sort({ "rank": -1 }).limit(2);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if ( lastSeen != null && doc.rank != lastSeen )
seenIds = [];
seenIds.push(doc._id);
if (!cursor.hasNext() || lastSeen == null)
lastSeen = doc.rank;
}
{ "_id": 1, "rank": 3 }
{ "_id": 3, "rank": 2 }
आप वास्तव में कितने "seenIds" धारण करते हैं, यह इस बात पर निर्भर करता है कि आपके परिणाम कितने "दानेदार" हैं, जहां उस मान के बदलने की संभावना है। इस मामले में आप जांच सकते हैं कि क्या वर्तमान "रैंक" स्कोर lastSeen
. के बराबर नहीं है मान लें और वर्तमान seenIds
. को त्याग दें सामग्री ताकि यह ज्यादा न बढ़े।
अभ्यास और सीखने के लिए "फॉरवर्ड पेजिंग" की यही मूल अवधारणा है।