Delen via


Indexering beheren in Azure Cosmos DB voor MongoDB

Met Azure Cosmos DB voor MongoDB kunt u indexering gebruiken om de queryprestaties te versnellen. In dit artikel leest u hoe u indexen beheert en optimaliseert voor het sneller ophalen van gegevens en een betere efficiëntie.

Indexering voor MongoDB-serverversie 3.6 en hoger

Azure Cosmos DB voor MongoDB-serverversie 3.6+ indexeert automatisch het _id veld en de shardsleutel (alleen in shardverzamelingen). De API dwingt de uniekheid van het _id veld per shardsleutel af.

De API voor MongoDB werkt anders dan Azure Cosmos DB for NoSQL, waarmee standaard alle velden worden geïndexeerd.

Indexeringsbeleid bewerken

Bewerk uw indexeringsbeleid in Data Explorer in Azure Portal. Voeg enkele veld- en jokertekenindexen toe vanuit de indexeringsbeleidseditor in Data Explorer:

Schermopname van de indexeringsbeleidseditor in Azure Cosmos DB voor MongoDB.

Notitie

U kunt geen samengestelde indexen maken met behulp van de indexeringsbeleidseditor in Data Explorer.

Indextypen

Eén veld

Maak een index voor één veld. De sorteervolgorde van de index met één veld maakt niet uit. Gebruik de volgende opdracht om een index voor het veld namete maken:

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

Maak dezelfde index name voor één veld in Azure Portal:

Schermopname van het toevoegen van een naamindex in de indexeringsbeleidseditor.

Een query maakt gebruik van meerdere indexen voor één veld, indien beschikbaar. Maak maximaal 500 indexen voor één veld per verzameling.

Samengestelde indexen (MongoDB-server versie 3.6+)

Gebruik in de API voor MongoDB samengestelde indexen met query's die meerdere velden tegelijk sorteren. Voor query's met meerdere filters die niet hoeven te worden gesorteerd, maakt u meerdere indexen voor één veld in plaats van een samengestelde index om te besparen op indexeringskosten.

Een samengestelde index of indexen van één veld voor elk veld in de samengestelde index resulteren in dezelfde prestaties voor het filteren in query's.

Samengestelde indexen op geneste velden worden niet standaard ondersteund vanwege beperkingen met matrices. Als een geneste veld geen matrix heeft, werkt de index zoals bedoeld. Als een geneste veld ergens op het pad een matrix heeft, wordt die waarde genegeerd in de index.

Een samengestelde index met people.dylan.age werkt bijvoorbeeld in dit geval omdat er geen matrix op het pad staat:

{
  "people": {
    "dylan": {
      "name": "Dylan",
      "age": "25"
    },
    "reed": {
      "name": "Reed",
      "age": "30"
    }
  }
}

Dezelfde samengestelde index werkt in dit geval niet omdat er een matrix in het pad staat:

{
  "people": [
    {
      "name": "Dylan",
      "age": "25"
    },
    {
      "name": "Reed",
      "age": "30"
    }
  ]
}

Schakel deze functie in voor uw databaseaccount door de mogelijkheid EnableUniqueCompoundNestedDocs in te schakelen.

Notitie

U kunt geen samengestelde indexen maken voor matrices.

Met de volgende opdracht maakt u een samengestelde index voor de velden name en age:

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

U kunt samengestelde indexen gebruiken om efficiënt te sorteren op meerdere velden tegelijk, zoals wordt weergegeven in het volgende voorbeeld:

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

U kunt de voorgaande samengestelde index ook gebruiken om efficiënt te sorteren op een query met de tegenovergestelde sorteervolgorde voor alle velden. Hier volgt een voorbeeld:

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

De volgorde van de paden in de samengestelde index moet echter exact overeenkomen met de query. Hier volgt een voorbeeld van een query waarvoor een extra samengestelde index nodig is:

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

Indexen met meerdere sleutels

Azure Cosmos DB maakt indexen met meerdere sleutels om inhoud in matrices te indexeren. Als u een veld indexeert met een matrixwaarde, indexeert Azure Cosmos DB automatisch elk element in de matrix.

Georuimtelijke indexen

Veel georuimtelijke operators profiteren van georuimtelijke indexen. Azure Cosmos DB voor MongoDB ondersteunt 2dsphere indexen. De API biedt nog geen ondersteuning voor 2d indexen.

Hier volgt een voorbeeld van het maken van een georuimtelijke index in het location veld:

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

Tekstindexen

Azure Cosmos DB voor MongoDB biedt geen ondersteuning voor tekstindexen. Gebruik Azure AI Search-integratie met Azure Cosmos DB voor zoekquery's voor tekstzoekopdrachten in tekenreeksen.

Wildcard-indexen

Gebruik jokertekenindexen om query's op onbekende velden te ondersteunen. Stel dat een verzameling gegevens bevat over gezinnen.

Dit is een onderdeel van een voorbeelddocument in die verzameling:

"children": [
  {
    "firstName": "Henriette Thaulow",
    "grade": "5"
  }
]

Hier volgt een ander voorbeeld met een andere set eigenschappen in children:

"children": [
  {
    "familyName": "Merriam",
    "givenName": "Jesse",
    "pets": [
      { "givenName": "Goofy" },
      { "givenName": "Shadow" }
    ]
  },
  {
    "familyName": "Merriam",
    "givenName": "John",
  }
]

Documenten in deze verzameling kunnen veel verschillende eigenschappen hebben. Als u alle gegevens in de children matrix wilt indexeren, maakt u afzonderlijke indexen voor elke eigenschap of maakt u één jokertekenindex voor de hele children matrix.

Een jokertekenindex maken

Gebruik de volgende opdracht om een jokertekenindex te maken voor alle eigenschappen binnen children:

db.coll.createIndex({"children.$**" : 1})
  • In tegenstelling tot in MongoDB kunnen jokertekenindexen meerdere velden in querypredicaten ondersteunen. Er is geen verschil in queryprestaties als u één jokertekenindex gebruikt in plaats van een afzonderlijke index te maken voor elke eigenschap.

Maak de volgende indextypen met behulp van jokertekensyntaxis:

  • Eén veld
  • Ruimtelijke gegevens

Alle eigenschappen indexeren

Maak een jokertekenindex voor alle velden met de volgende opdracht:

db.coll.createIndex( { "$**" : 1 } )

Jokertekenindexen maken met Data Explorer in Azure Portal:

Een jokertekenindex toevoegen in de indexeringsbeleidseditor

Notitie

Als u net begint met ontwikkelen, begint u met een jokertekenindex voor alle velden. Deze aanpak vereenvoudigt de ontwikkeling en maakt het eenvoudiger om query's te optimaliseren.

Documenten met veel velden kunnen hoge ru-kosten (Request Unit) hebben voor schrijf- en updates. Als u een schrijfintensieve werkbelasting hebt, gebruikt u afzonderlijk geïndexeerde paden in plaats van jokertekens.

Beperkingen

Jokertekenindexen bieden geen ondersteuning voor een van de volgende indextypen of eigenschappen:

  • Combinatie

  • TTL

  • Uniek

  • In tegenstelling tot in MongoDB kunt u in Azure Cosmos DB voor MongoDB geen jokertekenindexen gebruiken voor:

  • Een wildcard-index maken inclusief meerdere specifieke velden

    db.coll.createIndex(
      { "$**" : 1 },
      { "wildcardProjection " :
        {
          "children.givenName" : 1,
          "children.grade" : 1
        }
      }
    )
    
  • Een wildcard-index maken die meerdere specifieke velden uitsluit

    db.coll.createIndex(
      { "$**" : 1 },
      { "wildcardProjection" :
        {
          "children.givenName" : 0,
          "children.grade" : 0
        }
      }
    )
    

Als alternatief kunt u meerdere jokertekenindexen maken.

Indexeigenschappen

De volgende bewerkingen zijn gebruikelijk voor accounts die wire protocol versie 4.0 en eerdere versies gebruiken. Meer informatie over ondersteunde indexen en geïndexeerde eigenschappen.

Unieke indexen

Unieke indexen helpen ervoor te zorgen dat twee of meer documenten niet dezelfde waarde hebben voor geïndexeerde velden.

Voer de volgende opdracht uit om een unieke index in het student_id veld te maken:

db.coll.createIndex( { "student_id" : 1 }, {unique:true} )

{
  "_t" : "CreateIndexesResponse",
  "ok" : 1,
  "createdCollectionAutomatically" : false,
  "numIndexesBefore" : 1,
  "numIndexesAfter" : 4
}

Geef voor shardverzamelingen de shardsleutel (partitiesleutel) op om een unieke index te maken. Alle unieke indexen in een shardverzameling zijn samengestelde indexen en een van de velden is de shardsleutel. De shardsleutel moet het eerste veld in de indexdefinitie zijn.

Voer de volgende opdrachten uit om een shard-verzameling met de naam coll (met university als de shardsleutel) en een unieke index voor de student_id en university velden te maken:

db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
  "_t" : "ShardCollectionResponse",
  "ok" : 1,
  "collectionsharded" : "test.coll"
}
db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
  "_t" : "CreateIndexesResponse",
  "ok" : 1,
  "createdCollectionAutomatically" : false,
  "numIndexesBefore" : 3,
  "numIndexesAfter" : 4
}

Als u de "university":1 component weglaat in het vorige voorbeeld, ziet u het volgende foutbericht:

cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }

Beperkingen

Maak unieke indexen terwijl de verzameling leeg is.

Azure Cosmos DB voor MongoDB-accounts met continue back-up bieden geen ondersteuning voor het maken van een unieke index voor een bestaande verzameling. Voor een dergelijk account moeten unieke indexen worden gemaakt, samen met het maken van de verzameling. Dit moet en kan alleen worden gedaan met behulp van de opdrachten voor het maken van de verzamelingsextensie.

db.runCommand({customAction:"CreateCollection", collection:"coll", shardKey:"student_id", indexes:[
{key: { "student_id" : 1}, name:"student_id_1", unique: true}
]});

Unieke indexen voor geneste velden worden niet standaard ondersteund vanwege beperkingen met matrices. Als uw geneste veld geen matrix heeft, werkt de index zoals bedoeld. Als uw geneste veld ergens op het pad een matrix heeft, wordt die waarde genegeerd in de unieke index en blijft de uniekheid voor die waarde niet behouden.

In dit geval werkt een unieke index people.tom.age bijvoorbeeld omdat er geen matrix op het pad staat:

{
  "people": {
    "tom": {
      "age": "25"
    },
    "mark": {
      "age": "30"
    }
  }
}

Maar werkt in dit geval niet omdat er een matrix in het pad staat:

{
  "people": {
    "tom": [
      {
        "age": "25"
      }
    ],
    "mark": [
      {
        "age": "30"
      }
    ]
  }
}

Deze functie kan worden ingeschakeld voor uw databaseaccount door de functie 'EnableUniqueCompoundNestedDocs' in te schakelen.

TTL indexen

Als u documenten in een verzameling wilt laten verlopen, maakt u een TTL-index (Time-to-Live). Een TTL-index is een index in het _ts veld met een expireAfterSeconds waarde.

Voorbeeld:

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

Met de voorgaande opdracht worden alle documenten in de db.coll verzameling verwijderd die meer dan 10 seconden geleden zijn gewijzigd.

Notitie

Het _ts veld is specifiek voor Azure Cosmos DB en is niet toegankelijk vanaf MongoDB-clients. Het is een gereserveerde eigenschap (systeem) die het tijdstempel van de laatste wijziging van het document bevat.

Voortgang van index bijhouden

Versie 3.6+ van Azure Cosmos DB voor MongoDB ondersteunt de currentOp() opdracht om de voortgang van de index op een database-exemplaar bij te houden. Met deze opdracht wordt een document geretourneerd met informatie over actieve bewerkingen op een database-exemplaar. Gebruik de currentOp opdracht om alle actieve bewerkingen in systeemeigen MongoDB bij te houden. In Azure Cosmos DB voor MongoDB houdt deze opdracht alleen de indexbewerking bij.

Hier volgen enkele voorbeelden van het gebruik van de opdracht om de voortgang van de currentOp index bij te houden:

  • Indexvoortgang ophalen voor een verzameling:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • Indexvoortgang ophalen voor alle verzamelingen in een database:

    db.currentOp({"command.$db": <databaseName>})
    
  • Indexvoortgang ophalen voor alle databases en verzamelingen in een Azure Cosmos DB-account:

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

Voorbeelden van uitvoer van indexvoortgang

Details van de voortgang van de index geven het voortgangspercentage voor de huidige indexbewerking weer. Hier volgen voorbeelden van de indeling van het uitvoerdocument voor verschillende fasen van de indexvoortgang:

  • Een indexbewerking voor een 'foo'-verzameling en 'staafdatabase' die 60 procent voltooid is, heeft het volgende uitvoerdocument. In Inprog[0].progress.total het veld wordt 100 weergegeven als het voltooiingspercentage van het doel.

    {
      "inprog": [
        {
          ...
          "command": {
            "createIndexes": foo
            "indexes": [],
            "$db": bar
          },
          "msg": "Index Build (background) Index Build (background): 60 %",
          "progress": {
            "done": 60,
            "total": 100
          },
          ...
        }
      ],
      "ok": 1
    }
    
  • Als een indexbewerking zojuist is gestart op een 'foo'-verzameling en 'staaf'-database, kan het uitvoerdocument 0 procent voortgang weergeven totdat het een meetbaar niveau bereikt.

    {
      "inprog": [
        {
          ...
          "command": {
            "createIndexes": foo
            "indexes": [],
            "$db": bar
          },
          "msg": "Index Build (background) Index Build (background): 0 %",
          "progress": {
            "done": 0,
            "total": 100
          },
          ...
        }
      ],
      "ok": 1
    }
    
  • Wanneer de indexbewerking is voltooid, worden in het uitvoerdocument lege inprog bewerkingen weergegeven.

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

Updates van achtergrondindex

Indexupdates worden altijd op de achtergrond uitgevoerd, ongeacht de waarde die u instelt voor de eigenschap Achtergrondindex . Omdat indexupdates aanvraageenheden (RU's) met een lagere prioriteit gebruiken dan andere databaseacties, veroorzaken indexwijzigingen geen downtime voor schrijfbewerkingen, updates of verwijderingen.

Het toevoegen van een nieuwe index heeft geen invloed op de beschikbaarheid van leesbewerkingen. Query's gebruiken pas nieuwe indexen nadat de indextransformatie is voltooid. Tijdens de transformatie blijft de query-engine bestaande indexen gebruiken, zodat u vergelijkbare leesprestaties ziet als voordat u de indexeringswijziging start. Het toevoegen van nieuwe indexen riskeert geen onvolledige of inconsistente queryresultaten.

Als u indexen verwijdert en direct query's uitvoert die filteren op die verwijderde indexen, kunnen de resultaten inconsistent en onvolledig zijn totdat de indextransformatie is voltooid. De query-engine biedt geen consistente of volledige resultaten voor query's die filteren op zojuist verwijderde indexen. De meeste ontwikkelaars verwijderen geen indexen en voeren er vervolgens onmiddellijk query's op uit, dus deze situatie is onwaarschijnlijk.

Notitie

U kunt de voortgang van de index bijhouden.

reIndex opdracht

Met de reIndex opdracht worden alle indexen in een verzameling opnieuw gemaakt. In zeldzame gevallen kan het uitvoeren van de reIndex opdracht queryprestaties of andere indexproblemen in uw verzameling oplossen. Als u indexeringsproblemen ondervindt, probeert u de indexen opnieuw te maken met de reIndex opdracht.

Voer de reIndex opdracht uit met behulp van de volgende syntaxis:

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

Gebruik de volgende syntaxis om te controleren of het uitvoeren van de opdracht de reIndex queryprestaties in uw verzameling verbetert:

db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})

Voorbeelduitvoer:

{
  "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
}

Als reIndex de queryprestaties worden verbeterd, is requiresReIndex waar. Als reIndex de queryprestaties niet worden verbeterd, wordt deze eigenschap weggelaten.

Verzamelingen migreren met indexen

U kunt alleen unieke indexen maken wanneer de verzameling geen documenten bevat. Populaire MongoDB-migratiehulpprogramma's proberen unieke indexen te maken na het importeren van de gegevens. U kunt dit probleem omzeilen door handmatig de bijbehorende verzamelingen en unieke indexen te maken in plaats van het hulpprogramma voor migratie uit te voeren. U bereikt dit gedrag door mongorestore de --noIndexRestore vlag in de opdrachtregel te gebruiken.

Indexering voor MongoDB versie 3.2

Het indexeren van functies en standaardwaarden verschilt voor Azure Cosmos DB-accounts die gebruikmaken van versie 3.2 van het MongoDB-wire-protocol. Controleer de versie van uw account op feature-support-36.md#protocol-support en voer een upgrade uit naar versie 3.6 op upgrade-version.md.

Als u versie 3.2 gebruikt, worden in deze sectie belangrijke verschillen van versie 3.6 en hoger gemarkeerd.

Standaardindexen verwijderen (versie 3.2)

In tegenstelling tot versie 3.6 en hoger indexeert Azure Cosmos DB voor MongoDB versie 3.2 standaard elke eigenschap. Gebruik de volgende opdracht om deze standaardindexen voor een verzameling te verwijderen (coll):

db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }

Nadat u de standaardindexen hebt verwijderd, voegt u meer indexen toe, net zoals in versie 3.6 en hoger.

Samengestelde indexen (versie 3.2)

Samengestelde indexen verwijzen naar meerdere velden in een document. Als u een samengestelde index wilt maken, voert u een upgrade uit naar versie 3.6 of 4.0 op upgrade-version.md.

Wildcard-indexen (versie 3.2)

Als u een jokertekenindex wilt maken, voert u een upgrade uit naar versie 4.0 of 3.6 op upgrade-version.md.

Volgende stappen