Listování vašimi daty je jednou z nejběžnějších operací s MongoDB. Typickým scénářem je potřeba zobrazit výsledky po částech ve vašem uživatelském rozhraní. Pokud svá data zpracováváte hromadně, je také důležité správně nastavit strategii stránkování, aby se vaše zpracování dat mohlo škálovat.
Pojďme si projít příklad, abychom viděli různé způsoby, jak listovat daty v MongoDB. V tomto příkladu máme databázi CRM uživatelských dat, kterou potřebujeme procházet a zobrazovat 10 uživatelů najednou. Takže ve skutečnosti je velikost naší stránky 10. Zde je struktura našeho uživatelského dokumentu:
{ _id, name, company, state }
Přístup 1:Použití skip() a limit()
MongoDB nativně podporuje stránkování pomocí příkazů skip() a limit(). Direktiva skip(n) říká MongoDB, že by měla přeskočit ‚n‘ výsledků, a direktiva limit(n) říká MongoDB, že by měla omezit délku výsledku na ‚n‘ výsledků. Obvykle budete s kurzorem používat příkazy skip() a limit() – ale pro ilustraci scénáře poskytujeme příkazy konzoly, které by dosáhly stejných výsledků. Kvůli stručnosti kódu je také vyloučen kód pro kontrolu limitů:
//Page 1 db.users.find().limit (10) //Page 2 db.users.find().skip(10).limit(10) //Page 3 db.users.find().skip(20).limit(10) ........
Dostanete nápad. Obecně platí, že pro načtení stránky ‚n‘ kód vypadá takto:
db.users.find().skip(pagesize*(n-1)).limit(pagesize)
S rostoucí velikostí vašich dat má však tento přístup vážné problémy s výkonem. Důvodem je to, že pokaždé, když je dotaz proveden, je vytvořena úplná sada výsledků a server pak musí projít od začátku kolekce k zadanému offsetu. Jak se váš offset zvyšuje, tento proces se zpomaluje a zpomaluje. Tento proces také nevyužívá indexy efektivně. Přístup „skip()“ a „limit()“ je tedy obvykle užitečný, když máte malé soubory dat, a pokud pracujete s velkými soubory dat, budete chtít zvážit jiné přístupy.
Přístup 2:Použití find() a limit()
Důvodem, proč se předchozí přístup příliš neškáluje, je příkaz skip() a cílem v této části je implementovat stránkování bez použití příkazu ‚skip()‘. Za tímto účelem využijeme přirozené pořadí v uložených datech, jako je časové razítko nebo ID uložené v dokumentu. V tomto příkladu použijeme „_id“ uložené v každém dokumentu. „_id“ je struktura MongoDB ObjectID, což je 12bajtová struktura obsahující časové razítko, obrobené, procesní ID, čítač atd. Celková myšlenka je následující:
1. Získejte _id posledního dokumentu na aktuální stránce
2. Načíst dokumenty větší než toto „_id“ na další stránce
//Page 1 db.users.find().limit(pageSize); //Find the id of the last document in this page last_id = ... //Page 2 users = db.users.find({'_id'> last_id}). limit(10); //Update the last id with the id of the last document in this page last_id = ...
Tento přístup využívá přirozené pořadí, které existuje v poli „_id“. Vzhledem k tomu, že pole „_id“ je ve výchozím nastavení indexováno, je výkon operace hledání velmi dobrý. Pokud pole, které používáte, není indexováno, utrpí to váš výkon – proto je důležité zajistit, aby bylo pole indexováno.
Navíc, pokud chcete, aby vaše data byla tříděna v konkrétním pořadí pro stránkování, můžete také použít klauzuli sort() s výše uvedenou technikou. Je důležité zajistit, aby proces třídění využíval index pro nejlepší výkon. Můžete použít příponu .explain() k vašemu dotazu a určit toto:
users = db.users.find({'_id'> last_id}). sort(..).limit(10); //Update the last id with the id of the last document in this page last_id = ...
Jako vždy, pokud máte nějaké dotazy nebo připomínky, neváhejte nás kontaktovat na adrese [email protected].