sql >> Databasteknik >  >> NoSQL >> MongoDB

Snabbsökning med MongoDB

Att bläddra igenom dina data är en av de vanligaste operationerna med MongoDB. Ett typiskt scenario är behovet av att visa dina resultat i bitar i ditt användargränssnitt. Om du batchbearbetar din data är det också viktigt att få din personsökningsstrategi korrekt så att din databehandling kan skalas.

Låt oss gå igenom ett exempel för att se de olika sätten att bläddra igenom data i MongoDB. I det här exemplet har vi en CRM-databas med användardata som vi behöver bläddra igenom och visa 10 användare åt gången. Så i själva verket är vår sidstorlek 10. Här är strukturen för vårt användardokument:

{
    _id,
    name,
    company,
    state
}

Tillvägagångssätt 1:Använd skip() och limit()

MongoDB stöder inbyggt personsökning med kommandona skip() och limit(). Skip(n)-direktivet säger till MongoDB att det ska hoppa över 'n'-resultat, och limit(n)-direktivet instruerar MongoDB att det ska begränsa resultatlängden till 'n'-resultat. Vanligtvis kommer du att använda skip()- och limit()-direktiven med markören  men för att illustrera scenariot tillhandahåller vi konsolkommandon som skulle uppnå samma resultat. För att koden ska vara kort, är gränskontrollkoden också utesluten:

//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)
........

Du förstår idén. I allmänhet, för att hämta sida 'n' ser koden ut så här:

db.users.find().skip(pagesize*(n-1)).limit(pagesize)

Men när storleken på din data ökar, har den här metoden allvarliga prestandaproblem. Anledningen är att varje gång frågan exekveras byggs hela resultatuppsättningen upp, sedan måste servern gå från början av samlingen till den angivna offseten. När din offset ökar, blir denna process långsammare och långsammare. Denna process gör inte heller effektiv användning av indexen. Så vanligtvis är tillvägagångssätten "skip()" och "limit()" användbara när du har små datamängder, och om du arbetar med stora datamängder vill du överväga andra tillvägagångssätt.

Tillvägagångssätt 2:Använd find() och limit()

Anledningen till att det tidigare tillvägagångssättet inte skalas särskilt bra är kommandot skip() och målet i det här avsnittet är att implementera sökning utan att använda kommandot 'skip()'. För detta kommer vi att utnyttja den naturliga ordningen i lagrad data som en tidsstämpel eller ett id som lagras i dokumentet. I det här exemplet kommer vi att använda "_id" lagrat i varje dokument. '_id' är en MongoDB ObjectID-struktur som är en 12-byte struktur som innehåller en tidsstämpel, bearbetad, processid, räknare, etc. Den övergripande idén är följande:

1. Hämta _id för det sista dokumentet på den aktuella sidan
2. Hämta dokument som är större än detta "_id" på nästa sida

//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 = ...

Detta tillvägagångssätt utnyttjar den inneboende ordningen som finns i "_id"-fältet. Dessutom, eftersom "_id"-fältet är indexerat som standard, är prestandan för sökoperationen mycket bra. Om fältet du använder inte är indexerat kommer din prestation att lida – så det är viktigt att se till att fältet är indexerat.

Dessutom, om du vill att dina data sorteras i en viss ordning för din personsökning, kan du också använda sort()-satsen med ovanstående teknik. Det är viktigt att se till att sorteringsprocessen utnyttjar ett index för bästa resultat. Du kan använda suffixet .explain() till din fråga för att bestämma detta:

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 = ...

Som alltid om du har några frågor eller kommentarer är du välkommen att kontakta oss på [email protected].


  1. Varför finns det NYCKEL- och ARGV-matriser när man anropar Redis Lua-skript?

  2. Mongodb Öka värde inuti kapslad array

  3. MongoDB Ruby Driver 2.5.x problem med skiftlägeskänslighet med värdnamn på replikuppsättningar

  4. Dela sockets över separata nodeJS-instanser