Hantera indexering i Azure Cosmos DB-API för MongoDB

GÄLLER för: Azure Cosmos DB-API för MongoDB

Azure Cosmos DB API för MongoDB drar nytta av de grundläggande funktionerna för indexhantering i Azure Cosmos DB. Den här artikeln fokuserar på hur du lägger till index Azure Cosmos DB med hjälp av API:et för MongoDB. Index är specialiserade datastrukturer som gör att det går snabbare att köra frågor mot dina data.

Indexering för MongoDB-serverversion 3.6 och senare

Azure Cosmos DB API för MongoDB-serverversion 3.6+ indexerar automatiskt fältet och _id shardnyckeln (endast i fragmenterade samlingar). API:et framtvingar automatiskt unikhet _id för fältet per shardnyckel.

API:et för MongoDB fungerar annorlunda än Azure Cosmos DB SQL API: et, som indexerar alla fält som standard.

Redigera indexeringsprincip

Vi rekommenderar att du redigerar indexeringsprincipen i Datautforskaren i Azure Portal. . Du kan lägga till index med ett fält och jokertecken från redigeraren för indexeringsprincip i Datautforskaren:

Redigeringsprogram för indexeringsprincip

Anteckning

Du kan inte skapa sammansatta index med hjälp av redigeringsredigeraren för indexeringsprincip i Datautforskaren.

Indextyper

Enskilt fält

Du kan skapa index för ett enskilt 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 fältindex på name i Azure Portal:

Lägga till namnindex i redigeraren för indexeringsprincip

En fråga använder flera enskilda fältindex 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 din fråga behöver kunna sortera på flera fält samtidigt. För frågor med flera filter som inte behöver sorteras skapar du flera enskilda fältindex i stället för ett sammansatt index för att spara på indexeringskostnader.

Ett sammansatt index eller enskilda fältindex för varje fält i det sammansatta indexet resulterar i samma prestanda för filtrering i frågor.

Anteckning

Du kan inte skapa sammansatta index på kapslade egenskaper eller matriser.

Följande kommando skapar ett sammansatt index på 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 kräver ytterligare ett sammansatt index:

db.coll.find().sort({age:1,name:1})

Anteckning

Sammansatta index används bara i frågor som sorterar resultat. Skapa index för flera fält för frågor som har flera filter som inte behöver sorteras.

Index med flera nycklar

Azure Cosmos DB skapar index med flera nycklar för att indexera innehåll som lagras i matriser. Om du indexerar ett fält med ett matrisvärde Azure Cosmos DB automatiskt varje element i matrisen.

Geospatiala index

Många geospatiala operatorer kan dra nytta av geospatiala index. För närvarande Azure Cosmos DB API för MongoDB stöd för 2dsphere index. API:et stöder ännu 2d inte index.

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

db.coll.createIndex({ location : "2dsphere" })

Textindex

Azure Cosmos DB API för MongoDB stöder för närvarande inte textindex. För textsökningsfrågor på 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 med 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 indexera alla data i matrisen har du två alternativ: skapa separata index för varje enskild egenskap eller skapa ett children 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 har jokerteckenindex stöd för flera fält i fråge predikat . Det finns 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 Portal:

Lägga till jokerteckenindex i redigeraren för indexeringsprincip

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 skrivintensiva arbetsbelastning bör du därför välja enskilda indexsökvägar 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 MongoDB Azure Cosmos DB api för MongoDB du 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 betjänar 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.

Viktigt

Unika index kan bara skapas när samlingen är tom (innehåller inga dokument).

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 och student_id 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 -satsen i föregående "university":1 exempel returneras ett fel med följande meddelande:

kan inte skapa unikt index över {student_id : 1.0} med shardnyckelmönster { university: 1.0 }

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 _ts fältet med ett expireAfterSeconds värde.

Exempel:

globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})

Föregående kommando tar bort alla dokument i samlingen db.coll som inte har ändrats under de senaste 10 sekunderna.

Anteckning

Fältet _ts är specifikt för Azure Cosmos DB ä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 indexförloppet

Version 3.6+ Azure Cosmos DB API för MongoDB stöder kommandot för att spåra currentOp() 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 currentOp för att spåra alla pågående åtgärder i intern MongoDB. I Azure Cosmos DB API för 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 kommandot currentOp för att spåra indexförloppet:

  • Hämta indexförloppet för en samling:

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

    db.currentOp({"command.$db": <databaseName>})
    
  • Hämta indexförloppet för alla databaser och samlingar i ett Azure Cosmos-konto:

    db.currentOp({"command.createIndexes": { $exists : true } })
    

Exempel på förloppsutdata för index

Indexförloppet visar procentandelen förlopp för den aktuella indexåtgärden. Här är ett exempel som visar dokumentets format för utdata för olika steg i indexförloppet:

  • En indexåtgärd på en "foo"-samling och "bar"-databas som är 60 procent slutförd har följande utdatadokument. Fältet Inprog[0].progress.total visar 100 som målprocent för slutförande.

    {
          "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 på en "foo"-samling och "bar"-databas, kan utdatadokumentet visa 0 procents förlopp tills det 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 indexåtgärden pågår visas tomma åtgärder i inprog utdatadokumentet.

    {
        "inprog" : [],
        "ok" : 1
    }
    

Uppdateringar av bakgrundsindex

Oavsett vilket värde som anges för egenskapen Background index görs alltid indexuppdateringar i bakgrunden. Eftersom indexuppdateringar förbrukar enheter för programbegäran (RU:er) med lägre prioritet än andra databasåtgärder leder inte indexändringar till driftstopp för skrivningar, uppdateringar eller borttagningar.

Lästillgänglighet påverkas inte när du lägger till ett nytt index. Frågor använder bara nya index när indextransformering har slutförts. Under indextransformering fortsätter frågemotorn att använda befintliga index, så du kommer att se liknande läsprestanda under indexeringsomvandlingen 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 kör frågor direkt har filtren för de bort ignorerade indexen inkonsekventa och ofullständiga resultat tills indextransformeringen är klar. Om du tar bort index ger frågemotorn inte konsekventa eller fullständiga resultat när frågorna filtrerar på dessa nyligen borttagna index. De flesta utvecklare tar inte bort index och försöker sedan omedelbart fråga dem, så i praktiken är den här situationen osannolik.

Anteckning

Du kan spåra indexförloppet.

Kommandot ReIndex

Kommandot reIndex återskapar alla index i en samling. I vissa sällsynta fall kan du lösa problem med frågeprestanda eller andra index i samlingen genom att köra reIndex kommandot . Om du har problem med indexering rekommenderar vi att du återskapar indexen reIndex med kommandot .

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

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

Du kan använda syntaxen nedan för att kontrollera om körning av reIndex kommandot skulle förbättra frågeprestanda i din samling:

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 kommer requiresReIndex att vara sant. Om reIndex inte förbättrar frågeprestanda 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 tillåta att migreringsverktyget försöker. (Du kan uppnå det här mongorestore beteendet för genom --noIndexRestore att använda flaggan på kommandoraden.)

Indexering för MongoDB version 3.2

Tillgängliga indexeringsfunktioner och standardvärden är olika för Azure Cosmos-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+ Azure Cosmos DB API 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 på samma sätt 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