Hantera indexering i Azure Cosmos DB för MongoDB

GÄLLER FÖR: Mongodb

Azure Cosmos DB for MongoDB utnyttjar huvudfunktionerna 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-serverversion 3.6 och senare

Azure Cosmos DB for MongoDB server version 3.6+ indexerar _id automatiskt fältet och shardnyckeln (endast i fragmenterade samlingar). API:et framtvingar automatiskt unikheten för _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 indexeringsprincipen i Data Explorer inom Azure Portal. Du kan lägga till enstaka fält- och jokerteckenindex från indexeringsprincipredigeraren i Data Explorer:

Redigeraren indexeringsprincip

Anteckning

Du kan inte skapa sammansatta index med hjälp av indexeringsprincipredigeraren i Data Explorer.

Indextyper

Enskilt fält

Du kan skapa index för ett enskilt fält. Sorteringsordningen för ett fältindex spelar ingen roll. Följande kommando skapar ett index för fältet name:

db.coll.createIndex({name:1})

Du kan skapa samma index name för ett enda fält i Azure Portal:

Lägg till namnindex i indexeringsprincipredigeraren

En fråga använder flera index med ett enda fält där det är tillgängligt. Du kan skapa upp till 500 enfältsindex per samling.

Sammansatta index (MongoDB-serverversion 3.6+)

I API:et för MongoDB krävs sammansatta index om din fråga behöver kunna sortera i 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å indexeringskostnaderna.

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

Till exempel fungerar ett sammansatt index som innehåller people.tom.age 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 skicka in ett supportärende.

Anteckning

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, som du ser i 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 för 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})

Anteckning

Sammansatta index används endast i frågor som sorterar resultat. För frågor som har flera filter som inte behöver sorteras skapar du index för ett enda fält med flera fält.

Multikey-index

Azure Cosmos DB skapar multikey-index för att indexeras 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 drar nytta av geospatiala index. För närvarande stöder 2dsphere Azure Cosmos DB for MongoDB index. API:et stöder 2d ännu inte index.

Här är ett exempel på hur du skapar ett geospatialt index i fältet location :

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 Cognitive 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 enskilt jokerteckenindex i stället för att skapa ett separat index för varje egenskap.

Du kan skapa följande indextyper med hjälp av 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 Data Explorer i Azure Portal:

Lägga till jokerteckenindex i indexeringsprincipredigeraren

Anteckning

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 indexsökvägar individuellt i stället för att använda jokerteckenindex.

Begränsningar

Jokerteckenindex stöder inte någon av följande indextyper eller egenskaper:

  • Sammansättning
  • TTL
  • Unik

Till skillnad från i MongoDBkan du i Azure Cosmos DB för 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 så utgör alla unika index i en fragmenterad samling alltså sammansatta index där ett av fälten är en partitionsnyckel.

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 på kapslade fält stöds inte som standard på grund av limiationer med matriser. Om det kapslade fältet inte innehåller någon 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.

Till exempel fungerar ett unikt index på people.tom.age 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 skicka in en supportbegäran.

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.

Anteckning

Fältet _ts är specifikt för Azure Cosmos DB och är inte tillgängligt från MongoDB-klienter. Det är en reserverad (system)-egenskap 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 kommandot för att spåra alla pågående åtgärder i den inbyggda MongoDB.You use the currentOp command to track all in-progress operations in native MongoDB. I Azure Cosmos DB for MongoDB stöder det här kommandot endast spårning av indexåtgärden.

Här är några exempel som visar hur du använder currentOp kommandot för att spåra indexets förlopp:

  • Hämta indexets förlopp för en samling:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • Hämta indexet för alla samlingar i en databas:

    db.currentOp({"command.$db": <databaseName>})
    
  • Hämta indexet 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 den procentuella 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 startat 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 vilket värde som anges 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 driftstopp 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 har slutförts. 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.

Anteckning

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 reIndex köra kommandot . Om du har problem med indexering rekommenderar vi att du återskapar indexen reIndex med kommandot.

Du kan köra reIndex kommandot med följande syntax:

db.runCommand({ reIndex: <collection> })

Du kan använda syntaxen nedan för att kontrollera om körningen av 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 kommer att förbättra frågeprestanda , kräverReIndex kommer att vara 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 unika index när du har importerat data. 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 standardinställningar 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 beskriver det här avsnittet viktiga skillnader 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 ta bort 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