Hantera indexering i Azure Cosmos DB för MongoDB
GÄLLER FÖR: MongoDB
Azure Cosmos DB for MongoDB drar nytta av de viktigaste funktionerna för indexhantering i Azure Cosmos DB. Den här artikeln fokuserar på hur du lägger till index med Hjälp av Azure Cosmos DB för MongoDB. Index är specialiserade datastrukturer som gör det ungefär snabbare att köra frågor mot dina data.
Indexering för MongoDB-server version 3.6 och senare
Azure Cosmos DB för MongoDB-server version 3.6+ indexerar _id
automatiskt fältet och shardnyckeln (endast i fragmenterade samlingar). API:et framtvingar automatiskt det unika _id
fältet per shardnyckel.
API:et för MongoDB fungerar annorlunda än Azure Cosmos DB för NoSQL, som indexerar alla fält som standard.
Redigera indexeringsprincip
Vi rekommenderar att du redigerar din indexeringsprincip i Datautforskaren i Azure-portalen. Du kan lägga till index med enkla fält och jokertecken från indexeringsprincipredigeraren i Datautforskaren:
Kommentar
Du kan inte skapa sammansatta index med hjälp av indexeringsprincipredigeraren i Datautforskaren.
Indextyper
Enskilt fält
Du kan skapa index på ett enda fält. Sorteringsordningen för det enskilda fältindexet spelar ingen roll. Följande kommando skapar ett index i fältet name
:
db.coll.createIndex({name:1})
Du kan skapa samma index för ett enda fält i name
Azure-portalen:
En fråga använder flera index med ett enda fält där det är tillgängligt. Du kan skapa upp till 500 enskilda fältindex per samling.
Sammansatta index (MongoDB-serverversion 3.6+)
I API:et för MongoDB krävs sammansatta index om frågan behöver kunna sorteras på flera fält samtidigt. För frågor med flera filter som inte behöver sorteras skapar du flera index med ett enda fält i stället för ett sammansatt index för att spara på indexeringskostnader.
Ett sammansatt index eller ett enda fältindex för varje fält i det sammansatta indexet resulterar i samma prestanda för filtrering i frågor.
Sammansatta index i kapslade fält stöds inte som standard på grund av begränsningar med matriser. Om det kapslade fältet inte innehåller en matris fungerar indexet som avsett. Om det kapslade fältet innehåller en matris (var som helst på sökvägen) ignoreras det värdet i indexet.
Ett sammansatt index som innehåller people.dylan.age
fungerar till exempel i det här fallet eftersom det inte finns någon matris på sökvägen:
{
"people": {
"dylan": {
"name": "Dylan",
"age": "25"
},
"reed": {
"name": "Reed",
"age": "30"
}
}
}
Samma sammansatta index fungerar inte i det här fallet eftersom det finns en matris i sökvägen:
{
"people": [
{
"name": "Dylan",
"age": "25"
},
{
"name": "Reed",
"age": "30"
}
]
}
Den här funktionen kan aktiveras för ditt databaskonto genom att aktivera funktionen "EnableUniqueCompoundNestedDocs".
Kommentar
Du kan inte skapa sammansatta index på matriser.
Följande kommando skapar ett sammansatt index för fälten name
och age
:
db.coll.createIndex({name:1,age:1})
Du kan använda sammansatta index för att sortera effektivt på flera fält samtidigt, enligt följande exempel:
db.coll.find().sort({name:1,age:1})
Du kan också använda föregående sammansatta index för att effektivt sortera på en fråga med motsatt sorteringsordning på alla fält. Här är ett exempel:
db.coll.find().sort({name:-1,age:-1})
Sekvensen för sökvägarna i det sammansatta indexet måste dock exakt matcha frågan. Här är ett exempel på en fråga som skulle kräva ytterligare ett sammansatt index:
db.coll.find().sort({age:1,name:1})
Multikey-index
Azure Cosmos DB skapar multikey-index för indexering av innehåll som lagras i matriser. Om du indexerar ett fält med ett matrisvärde indexerar Azure Cosmos DB automatiskt varje element i matrisen.
Geospatiala index
Många geospatiala operatorer kommer att dra nytta av geospatiala index. För närvarande stöder 2dsphere
Azure Cosmos DB for MongoDB index. API:et har ännu inte stöd för 2d
index.
Här är ett exempel på hur du skapar ett geospatialt index i location
fältet:
db.coll.createIndex({ location : "2dsphere" })
Textindex
Azure Cosmos DB for MongoDB stöder för närvarande inte textindex. För textsökningsfrågor i strängar bör du använda Azure AI Search-integrering med Azure Cosmos DB.
Jokerteckenindex
Du kan använda jokerteckenindex för att stödja frågor mot okända fält. Anta att du har en samling som innehåller data om familjer.
Här är en del av ett exempeldokument i samlingen:
"children": [
{
"firstName": "Henriette Thaulow",
"grade": "5"
}
]
Här är ett annat exempel, den här gången med en något annorlunda uppsättning egenskaper i children
:
"children": [
{
"familyName": "Merriam",
"givenName": "Jesse",
"pets": [
{ "givenName": "Goofy" },
{ "givenName": "Shadow" }
]
},
{
"familyName": "Merriam",
"givenName": "John",
}
]
I den här samlingen kan dokument ha många olika möjliga egenskaper. Om du vill indexering av alla data i matrisen children
har du två alternativ: skapa separata index för varje enskild egenskap eller skapa ett jokerteckenindex för hela children
matrisen.
Skapa ett jokerteckenindex
Följande kommando skapar ett jokerteckenindex för alla egenskaper i children
:
db.coll.createIndex({"children.$**" : 1})
Till skillnad från i MongoDB kan jokerteckenindex stödja flera fält i frågepredikat. Det blir ingen skillnad i frågeprestanda om du använder ett enda jokerteckenindex i stället för att skapa ett separat index för varje egenskap.
Du kan skapa följande indextyper med jokerteckensyntax:
- Enskilt fält
- Geospatial
Indexera alla egenskaper
Så här kan du skapa ett jokerteckenindex för alla fält:
db.coll.createIndex( { "$**" : 1 } )
Du kan också skapa jokerteckenindex med hjälp av Datautforskaren i Azure-portalen:
Kommentar
Om du precis har börjat utveckla rekommenderar vi starkt att du börjar med ett jokerteckenindex för alla fält. Detta kan förenkla utvecklingen och göra det enklare att optimera frågor.
Dokument med många fält kan ha en hög ru-avgift (Request Unit) för skrivningar och uppdateringar. Om du har en skrivintensiv arbetsbelastning bör du därför välja att individuellt indexsökvägar i stället för att använda jokerteckenindex.
Kommentar
Stöd för unikt index för befintliga samlingar med data finns i förhandsversionen. Den här funktionen kan aktiveras för ditt databaskonto genom att aktivera funktionen "EnableUniqueIndexReIndex".
Begränsningar
Jokerteckenindex stöder inte någon av följande indextyper eller egenskaper:
- Sammansättning
- TTL
- Unik
Till skillnad från i MongoDB kan du i Azure Cosmos DB for MongoDB inte använda jokerteckenindex för:
Skapa ett jokerteckenindex som inkluderar flera specifika fält
db.coll.createIndex( { "$**" : 1 }, { "wildcardProjection " : { "children.givenName" : 1, "children.grade" : 1 } } )
Skapa ett jokerteckenindex som exkluderar flera specifika fält
db.coll.createIndex( { "$**" : 1 }, { "wildcardProjection" : { "children.givenName" : 0, "children.grade" : 0 } } )
Alternativt kan du skapa flera jokerteckenindex.
Indexegenskaper
Följande åtgärder är vanliga för konton som hanterar wire protocol version 4.0 och konton som betjänar tidigare versioner. Du kan lära dig mer om index som stöds och indexerade egenskaper.
Unika index
Unika index är användbara för att framtvinga att två eller flera dokument inte innehåller samma värde för indexerade fält.
Följande kommando skapar ett unikt index i fältet student_id
:
globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
{
"_t" : "CreateIndexesResponse",
"ok" : 1,
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 4
}
För fragmenterade samlingar måste du ange shardnyckeln (partition) för att skapa ett unikt index. Med andra ord är alla unika index i en fragmenterad samling sammansatta index där ett av fälten är shardnyckeln. Det första fältet i ordningen ska vara shardnyckeln.
Följande kommandon skapar en fragmenterad samling coll
(shardnyckeln är university
) med ett unikt index för fälten student_id
och university
:
globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
"_t" : "ShardCollectionResponse",
"ok" : 1,
"collectionsharded" : "test.coll"
}
globaldb:PRIMARY> db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
"_t" : "CreateIndexesResponse",
"ok" : 1,
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4
}
Om du utelämnar "university":1
satsen i föregående exempel returneras ett fel med följande meddelande:
cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }
Begränsningar
Unika index måste skapas medan samlingen är tom.
Unika index för kapslade fält stöds inte som standard på grund av begränsningar med matriser. Om det kapslade fältet inte innehåller en matris fungerar indexet som avsett. Om det kapslade fältet innehåller en matris (var som helst på sökvägen) ignoreras det värdet i det unika indexet och unikheten bevaras inte för det värdet.
Ett unikt index på people.tom.age fungerar till exempel i det här fallet eftersom det inte finns någon matris på sökvägen:
{ "people": { "tom": { "age": "25" }, "mark": { "age": "30" } } }
men fungerar inte i det här fallet eftersom det finns en matris i sökvägen:
{ "people": { "tom": [ { "age": "25" } ], "mark": [ { "age": "30" } ] } }
Den här funktionen kan aktiveras för ditt databaskonto genom att aktivera funktionen "EnableUniqueCompoundNestedDocs".
TTL-index
Om du vill aktivera förfallodatum för dokument i en viss samling måste du skapa ett TTL-index (time to live). Ett TTL-index är ett index i fältet _ts
med ett expireAfterSeconds
värde.
Exempel:
globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})
Föregående kommando tar bort alla dokument i db.coll
samlingen som inte har ändrats under de senaste 10 sekunderna.
Kommentar
Fältet _ts är specifikt för Azure Cosmos DB och är inte tillgängligt från MongoDB-klienter. Det är en reserverad egenskap (system) som innehåller tidsstämpeln för dokumentets senaste ändring.
Spåra indexstatus
Version 3.6+ av Azure Cosmos DB for MongoDB stöder currentOp()
kommandot för att spåra indexförloppet på en databasinstans. Det här kommandot returnerar ett dokument som innehåller information om pågående åtgärder på en databasinstans. Du använder currentOp
kommandot för att spåra alla pågående åtgärder i den interna MongoDB. I Azure Cosmos DB for MongoDB stöder det här kommandot endast spårning av indexåtgärden.
Här följer några exempel som visar hur du använder currentOp
kommandot för att spåra indexets förlopp:
Hämta index förloppet för en samling:
db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
Hämta index förloppet för alla samlingar i en databas:
db.currentOp({"command.$db": <databaseName>})
Hämta indexstatusen för alla databaser och samlingar i ett Azure Cosmos DB-konto:
db.currentOp({"command.createIndexes": { $exists : true } })
Exempel på index förloppsutdata
Förloppsinformationen för indexet visar procentandelen för förloppet för den aktuella indexåtgärden. Här är ett exempel som visar utdatadokumentformatet för olika steg i indexets förlopp:
En indexåtgärd i en "foo"-samling och en "bar"-databas som är 60 procent färdig kommer att ha följande utdatadokument. Fältet
Inprog[0].progress.total
visar 100 som målslutprocent.{ "inprog" : [ { ………………... "command" : { "createIndexes" : foo "indexes" :[ ], "$db" : bar }, "msg" : "Index Build (background) Index Build (background): 60 %", "progress" : { "done" : 60, "total" : 100 }, …………..….. } ], "ok" : 1 }
Om en indexåtgärd precis har startats i en "foo"-samling och en "bar"-databas kan utdatadokumentet visa 0 procents förlopp tills den når en mätbar nivå.
{ "inprog" : [ { ………………... "command" : { "createIndexes" : foo "indexes" :[ ], "$db" : bar }, "msg" : "Index Build (background) Index Build (background): 0 %", "progress" : { "done" : 0, "total" : 100 }, …………..….. } ], "ok" : 1 }
När den pågående indexåtgärden är klar visar utdatadokumentet tomma
inprog
åtgärder.{ "inprog" : [], "ok" : 1 }
Uppdateringar av bakgrundsindex
Oavsett det värde som angetts för egenskapen Background Index görs indexuppdateringar alltid i bakgrunden. Eftersom indexuppdateringar använder enheter för programbegäran (RU: er) med lägre prioritet än andra databasåtgärder resulterar indexändringar inte i någon stilleståndstid för skrivningar, uppdateringar eller borttagningar.
Lästillgängligheten påverkas inte när du lägger till ett nytt index. Frågor använder bara nya index när indextransformeringen är klar. Under indextransformeringen fortsätter frågemotorn att använda befintliga index, så du ser liknande läsprestanda under indexeringstransformeringen som du hade observerat innan du initierade indexeringsändringen. När du lägger till nya index finns det heller ingen risk för ofullständiga eller inkonsekventa frågeresultat.
När du tar bort index och omedelbart kör frågor som har filter på de borttagna indexen kan resultaten vara inkonsekventa och ofullständiga tills indextransformeringen är klar. Om du tar bort index ger frågemotorn inte konsekventa eller fullständiga resultat när frågor filtrerar på dessa nyligen borttagna index. De flesta utvecklare släpper inte index och försöker sedan omedelbart fråga dem, så i praktiken är den här situationen osannolik.
Kommentar
Du kan spåra index förloppet.
ReIndex-kommando
Kommandot reIndex
återskapar alla index i en samling. I vissa sällsynta fall kan frågeprestanda eller andra indexproblem i samlingen lösas genom att köra reIndex
kommandot . Om du har problem med indexering är det en rekommenderad metod att återskapa indexen reIndex
med kommandot.
Du kan köra reIndex
kommandot med hjälp av följande syntax:
db.runCommand({ reIndex: <collection> })
Du kan använda syntaxen nedan för att kontrollera om reIndex
kommandot skulle förbättra frågeprestandan i samlingen:
db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})
Exempel på utdata:
{
"database" : "myDB",
"collection" : "myCollection",
"provisionedThroughput" : 400,
"indexes" : [
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "myDB.myCollection",
"requiresReIndex" : true
},
{
"v" : 1,
"key" : {
"b.$**" : 1
},
"name" : "b.$**_1",
"ns" : "myDB.myCollection",
"requiresReIndex" : true
}
],
"ok" : 1
}
Om reIndex
förbättrar frågeprestandan är requiresReIndex sant. Om reIndex
inte förbättrar frågeprestandan utelämnas den här egenskapen.
Migrera samlingar med index
För närvarande kan du bara skapa unika index när samlingen inte innehåller några dokument. Populära MongoDB-migreringsverktyg försöker skapa de unika indexen när data har importerats. Om du vill kringgå det här problemet kan du manuellt skapa motsvarande samlingar och unika index i stället för att låta migreringsverktyget prova. (Du kan uppnå det här beteendet med mongorestore
hjälp --noIndexRestore
av flaggan på kommandoraden.)
Indexering för MongoDB version 3.2
Tillgängliga indexeringsfunktioner och standardvärden skiljer sig åt för Azure Cosmos DB-konton som är kompatibla med version 3.2 av MongoDB-trådprotokollet. Du kan kontrollera ditt kontos version och uppgradera till version 3.6.
Om du använder version 3.2 beskrivs viktiga skillnader i det här avsnittet med version 3.6+.
Ta bort standardindex (version 3.2)
Till skillnad från version 3.6+ av Azure Cosmos DB för MongoDB indexerar version 3.2 varje egenskap som standard. Du kan använda följande kommando för att släppa dessa standardindex för en samling (coll
):
> db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }
När du har släppt standardindexen kan du lägga till fler index som i version 3.6+.
Sammansatta index (version 3.2)
Sammansatta index innehåller referenser till flera fält i ett dokument. Om du vill skapa ett sammansatt index uppgraderar du till version 3.6 eller 4.0.
Jokerteckenindex (version 3.2)
Om du vill skapa ett jokerteckenindex uppgraderar du till version 4.0 eller 3.6.
Nästa steg
- Indexering i Azure Cosmos DB
- Ta bort data från Azure Cosmos DB automatiskt med hjälp av förfallodatum
- Mer information om relationen mellan partitionering och indexering finns i artikeln Om hur du kör frågor mot en Azure Cosmos DB-container .
- Försöker du planera kapacitet för en migrering till Azure Cosmos DB? Du kan använda information om ditt befintliga databaskluster för kapacitetsplanering.
- Om allt du vet är antalet virtuella kärnor och servrar i ditt befintliga databaskluster läser du om att uppskatta enheter för begäranden med virtuella kärnor eller virtuella kärnor
- Om du känner till vanliga begärandefrekvenser för din aktuella databasarbetsbelastning kan du läsa om att uppskatta enheter för begäranden med azure Cosmos DB-kapacitetshanteraren