sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB Multikey Index &Index Intersection Bounds

MongoDB har bra stöd för arrayer och ger mycket flexibilitet i ditt dokumentläge. Du kan till exempel bädda in arrayer i dokument och även bädda in dokument i arrayer etc. Att arbeta med arrayer har dock ett antal gotcha i MongoDB. I det här inlägget kommer vi att titta på några av problemen som MongoDB har med index och arrayer.

Multikey-index

I MongoDB kan du indexera ett arrayfält för att skapa en indexpost för varje element i arrayen. Det resulterande indexet kallas ett "multikey"-index. Multikey-index kan skapas över skalära värden eller inbäddade dokument. Mer information om multikey-index finns i den här dokumentationen.

Multikey-index, även om de är användbara, har flera begränsningar:

  • Om du skapar ett sammansatt flernyckelindex har du minst ett fält som är en array.
  • Ett sammansatt index kan inte vara en shard-nyckel.
  • Ett sammansatt index kan inte vara ett hashat index.
MongoDB Multikey Index Begränsningar - Vad du ska hålla utkik efter i dina frågorKlicka för att tweeta

En av de mest intressanta aspekterna av multikey-index är hur indexskärningsgränser beräknas.

Index skär gränser

Så här definierar MongoDB-dokumentationen index skärningsgränser:

"Gränserna för en indexskanning definierar de delar av ett index som ska sökas under en sökning. När det finns flera predikat över ett index, kommer MongoDB att försöka kombinera gränserna för dessa predikat genom antingen skärning eller kompoundering för att producera en skanning med mindre gränser.”

Räckviddsfrågor på matriser

Låt oss komma igång med ett enkelt exempel för att se hur MongoDB beräknar indexgränser för frågor på arrayer. Antag att vi har följande tre dokument i en samling:

{x:65}{x:35}{x:[12,95]}

Vi utfärdar följande fråga:

db.coll.find({x :{ $gt :22, $lt:55})

Frågan är enkel nog. Du skulle förvänta dig att svaret skulle vara {x:35} men frågan returnerar:

{x:35}{x:[25,95]}

Anledningen kommer från hur MongoDB hanterar arrayer. Samma element i arrayen behöver inte matcha båda villkoren; så länge det finns ett element som matchar varje villkor är det en matchning. Så i det här fallet är gränserna [22, Infinity] och [-Infinity, 55]. Eftersom en "elemMatch"-operator inte används, använder MongoDB inte indexskärningen. MongoDB specificerar inte vilket av dessa intervall [22, Infinity] eller [-Infinity, 55] som kommer att användas för exekvering av frågan.

Om vi ​​vill använda indexkorsningen måste vi använda följande fråga:

db.coll.find(x :{ $elemMatch:{$gt :22,$lt:55}})

När du använder detta skär MongoDB indexgränserna och använder [22, 55] som gränser. Som förväntat returnerar denna fråga inga resultat (elemMatch matchar inte icke-arrayer). Så i grund och botten är intervallfrågor på arrayer ganska värdelösa utan $elemMatch-operatorn.

Sammansatta flernyckelindex – blanda array- och icke-arrayfält

Överväg en samling med följande dokument:

{item:35, prices:[250,35]}......{item:106, prices:[1500,65]}

Vi lägger till ett sammansatt index på den här samlingen:

db.ensureIndex({artikel:1, priser:1});

Låt oss nu köra en enkel fråga:

db. coll. find({artikel:{$gt:12, $lt:65}});

Frågan ser tillräckligt enkel ut, eftersom vi använder ett objekt som inte består av ett array med ett fast intervall. Jag förväntar mig att index skärningsgränser är ungefär som objekt:[[12,65] ] för frågan, men om du kör en förklara kommer du att se detta:

"indexBounds" :{"item" :[ [ -Infinity, 65 ] ],"prices" :[ [ { "$minElement" :1 }, { "$maxElement" :1 } ] ]}, 

Anledningen är att MongoDB upptäcker att detta är ett flernyckelindex och inte bearbetar skärningspunkten för indexgränser, oavsett det faktum att din fråga inte använder några matrisfält. Moralen i berättelsen är att när du blandar array- och icke-arrayfält i ett index, håll alltid ett öga på gränserna för indexkorsningen. Oddsen är att det inte är effektivt.


  1. Kan inte använda mongo-kommandot, visar kommandot som inte finns på mac

  2. Skapa ett ISO-datumobjekt i javascript

  3. Försenad exekvering / schemaläggning med Redis?

  4. Redis förslag för val av datatyp