Index partiel - Amazon DocumentDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Index partiel

Un index partiel indexe les documents d'une collection qui répond à un critère de filtre spécifié. La fonctionnalité d'index partiel est prise en charge dans les clusters basés sur des instances Amazon DocumentDB 5.0.

Création d'un index partiel

Pour créer un index partiel, utilisez la createIndex() méthode avec l'partialFilterExpressionoption. Par exemple, l'opération suivante crée un index composé unique dans la collection de commandes qui indexe les documents ayant un OrderID et dont le isDelivered champ est vrai :

db.orders.createIndex( {"category": 1, "CustomerId": 1, "OrderId": 1}, {"unique": true, "partialFilterExpression": {"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ]} } )

Opérateurs pris en charge

  • $eq

  • $exists

  • $and (uniquement au niveau supérieur)

  • $gt/$gte/$lt/$lte (le scan d'index n'est utilisé que lorsque le filtre, défini dans la requête, correspond exactement à l'expression du filtre partiel) (voir Limitations)

Requête utilisant un index partiel

Les modèles de requête suivants sont possibles à l'aide d'index partiels :

  • Le prédicat de requête correspond exactement à l'expression du filtre d'index partiel :

    db.orders.find({"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ]}).explain()
  • Le résultat attendu du filtre de requête est un sous-ensemble logique du filtre partiel :

    db.orders.find({"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}}, {"OrderAmount": {"$eq": "5"}} ]}).explain()
  • Un sous-prédicat de la requête peut être utilisé conjointement avec d'autres index :

    db.orders.createIndex({"anotherIndex":1}) db.orders.find({ "$or": [ {"$and": [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ]}, {"anotherIndex": {"$eq": 5}} ] }).explain()
Note

Un planificateur de requêtes peut choisir d'utiliser une analyse de collection plutôt qu'une analyse d'index s'il est efficace de le faire. Cela se produit généralement pour de très petites collections ou des requêtes qui renvoient une grande partie d'une collection.

Fonctionnalités de l'index partiel

Répertorier les index partiels

Répertoriez les index partiels à partialFilterExpression l'aide de l'getIndexopération. Par exemple, l'getIndexopération émise dans répertorie les index partiels avec les champs key, name et PartialFilterExpressions :

db.orders.getIndexes()

Cet exemple renvoie le résultat suivant :

[ { "v" : 4, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "ecommerceApp.orders" }, { "v" : 4, "unique" : true, "key" : { "category" : 1, "" : 1, "CustomerId" : 1, "OrderId" : 1 }, "name" : "category_1_CustID_1_OrderId_1", "ns" : "ecommerceApp.orders", "partialFilterExpression" : { "$and" : [ {"OrderId": {"$exists": true}}, {"isDelivered": {"$eq": false}} ] } } ]

Expression de filtre partiel multiple sur la même clé:order

Différents index partiels peuvent être créés pour les mêmes combinaisons de champs (key:order). Ces index doivent porter un nom différent.

db.orders.createIndex( {"OrderId":1}, { name:"firstPartialIndex", partialFilterExpression:{"OrderId":{"$exists": true}} } )
db.orders.createIndex( {"OrderId":1}, { name:"secondPartialIndex", partialFilterExpression:{"OrderId":{"$gt": 1000}} } )

Exécutez getIndexes l'opération pour répertorier tous les index de la collection :

db.orders.getIndexes()

Ces exemples renvoient le résultat suivant :

[ { "v" : 4, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "ecommerceApp.orders" }, { "v" : 4, "key" : { "OrderId" : 1 }, "name" : "firstPartialIndex", "ns" : "ecommerceApp.orders", "partialFilterExpression" : {"OrderId":{"$exists": true}} }, { "v" : 4, "key" : { "OrderId" : 1 }, "name" : "secondPartialIndex", "ns" : "ecommerceApp.orders", "partialFilterExpression" : {"OrderId":{"$gt": 1000}} } ]
Important

Les noms d'index doivent être différents et ne doivent être supprimés que par leur nom.

Index avec propriétés partielles et TTL

Vous pouvez également créer des index dotés de propriétés partielles et TTL en spécifiant à la fois les deux partialFilterExpression et les expireAfterSeconds options lors de la création de l'index. Cela vous permet de mieux contrôler les documents qui sont désormais supprimés d'une collection.

Par exemple, il se peut que vous disposiez d'un index TTL qui identifie les documents à supprimer après un certain laps de temps. Vous pouvez désormais définir des conditions supplémentaires concernant le moment où vous devez supprimer des documents à l'aide de l'option d'indexation partielle :

db.orders.createIndex( { "OrderTimestamp": 1 }, { expireAfterSeconds: 3600 , partialFilterExpression: { "isDelivered": { $eq: true } } } )

Cet exemple renvoie le résultat suivant :

{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1, "operationTime" : Timestamp(1234567890, 1) }

Exécutez l'getIndexesopération pour répertorier les index présents dans la collection :

db.orders.getIndexes() [ { "v" : 4, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.orders" }

Cet exemple renvoie le résultat suivant :

[ { "v": 4, "key": { "_id": 1 }, "name": "_id_", "ns": "ecommerceApp.orders" }, { "v": 4, "key": { "OrderTimestamp": 1 }, "name": "OrderTimestamp_1", "ns": "ecommerceApp.orders", "partialFilterExpression": { "isDelivered": { "$eq": true } }, "expireAfterSeconds": 3600 } ]

Limitations partielles de l'indice

Les limites suivantes s'appliquent à la fonction d'index partiel :

  • Les requêtes d'inégalité dans Amazon DocumentDB n'utiliseront un index partiel que lorsque le prédicat du filtre de requêtes correspond exactement au même type de données partialFilterExpression et qu'il est du même type de données.

    Note

    $hintNe peut même pas être utilisé pour forcer IXSCAN dans le cas ci-dessus.

    Dans l'exemple suivant, le partialFilterExpression est uniquement appliqué field1 mais pas field2 :

    db.orders.createIndex( {"OrderAmount": 1}, {"partialFilterExpression": { OrderAmount : {"$gt" : 5}}} ) db.orders.find({OrderAmount : {"$gt" : 5}}) // Will use partial index db.orders.find({OrderAmount : {"$gt" : 6}}) // Will not use partial index db.orders.find({OrderAmount : {"$gt" : Decimal128(5.00)}}) // Will not use partial index
  • A partialFilterExpression avec opérateurs de tableau ne sont pas pris en charge. L'opération suivante va générer une erreur :

    db.orders.createIndex( {"CustomerId":1}, {'partialFilterExpression': {'OrderId': {'$eq': [1000, 1001, 1002]}}} )
  • Les opérateurs suivants ne sont pas pris en charge partialFilterExpression sur le terrain :

    • $all(opérateur de tableau)

    • $mod(opérateur de tableau)

    • $or

    • $xor

    • $not

    • $nor

  • Le type de données de l'expression du filtre et celui du filtre doivent être identiques.