Pourquoi mes requêtes de liste renvoient-elles un nombre d'éléments erroné lorsque j'utilise DynamoDB avec AWS AppSync ?

Lecture de 5 minute(s)
0

Mes requêtes de liste renvoient un nombre d'éléments erroné lorsque j'utilise Amazon DynamoDB avec AWS AppSync. Comment puis-je résoudre ce problème ?

Brève description

Lorsque vous utilisez une requête de liste avec AWS AppSync et Amazon DynamoDB, DynamoDB effectue une opération d'analyse sur la table et renvoie un certain nombre d'éléments évalués. Si vous fournissez une opération FilterExpression sur la demande, alors DynamoDB applique FilterExpression uniquement à ces éléments évalués.

Le nombre d'éléments vérifiés par l’analyse dépend de la variable de limite appliquée à la requête. Si aucune limite n'est appliquée, alors DynamoDB utilise la limite par défaut configurée dans le modèle de mappage de la demande. L'analyse renvoie uniquement les éléments évalués et qui correspondent à l'expression de filtre. Pour renvoyer le nombre d'éléments attendu, il convient d’ajuster la variable de limite.

Vous pouvez augmenter la limite par défaut de votre modèle de mappage, ou bien ajouter une variable de limite à la requête GraphQL de la liste. Toutefois, vous ne pouvez évaluer qu’un maximum de 1 Mo d’éléments. Si votre opération d’analyse dépasse 1 Mo de données, alors vous pouvez utiliser la pagination pour obtenir le reste des données. Pour vous aider à interroger une base de données qui présente des milliers d'éléments, vous pouvez indexer vos données afin de filtrer les résultats en fonction d'un champ commun.

Solution

Augmenter la limite par défaut

Dans l'exemple de modèle de mappage suivant pour une API générée par AWS Amplify, la limite par défaut est de 100 :

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )
#set( $ListRequest = {
  "version": "2018-05-29",
  "limit": $limit
} )

Pour évaluer plus d'éléments, modifiez la limite par défaut dans le modèle de mappage. Sinon, vous pouvez ajouter une variable de limite à la requête de liste. Par exemple, dans la requête de liste suivante, la limite est définie sur 1 000 :

query MyQuery {
  listEmployees(limit: 1000) {
    items {
      id
      name
      company
    }
  }
}

Paginer avec AWS AppSync

Pour paginer avec AWS AppSync, ajoutez un argument nextToken à votre requête GraphQL.

Exemple de requête :

query MyQuery {
  listEmployees{
    items {
      id
      name
      company
    }
    nextToken
  }
}

Remarque : la valeur nextToken renvoyée par la requête est soit nulle, soit une chaîne longue commençant par ey et se terminant par =. Cette valeur représente la dernière clé évaluée. Si la valeur est nulle, il n'y a plus d'éléments à évaluer dans la table. S'il s'agit d'une chaîne longue, alors il y a d'autres éléments à évaluer.

Par exemple :

"nextToken": "eyJ2ZXJzaW9uIjoyLCJ0b2tlbiI6IkFRSUNBSGg5OUIvN3BjWU41eE96NDZJMW5GeGM4WUNGeG1acmFOMUpqajZLWkFDQ25BRkQxUjREaVVxMkd1aDZNZ2ZTMmhPMUFBQUNIVENDQWhrR0NTcUdTSWIzRFFFSEJxQ0NBZ293Z2dJR0FnRUFNSUlCL3dZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF4c0RFY1ZZUGpaRDFxbDcxNENBUkNBZ2dIUWkwaGtJYytoU04vRFMzL3VQT2ZDMnpIV1dBVkg4LzU3TWFwMGZWSHVackt1VmV4emRvTVQrNml6VC9RdDRsSVNGN1pmc3NWTHVvcnJpRE1RZVE5ckNyd3J4dmNOY3ZZUzhTc21PRFFkaTUreVhQcDJ1OENaK29Sd2wrV3VoOGJ0YlBpQXQydjRNdmw2L09jRzRHV2RxRmFjeTFDRjRyK2FPd29velRTV3NqMTd4OUpwVi93cHVYc2tTN2R5TmYxa3JJS3hSL3BMWlY5M3JPSlVocEpDV2xEL3Y1UU5JdGJoOWpyaTI3N09LbUZsVlh3bDRna3hDa1kzeGZMNjZrM2dZY0hpbHlUOE1GUnBLU0VCTFE3RGEzSlJtUG8xUkJvQ051K3dBTkwwd09Vckp0N1BFb0QvTVRrenZDV1lCTXhVaUhaRDdrM3Y5a2FJS2NScHY0ajhuTDJ2Nk9EZ3plTjgwN1RtRFViM21rRUsrakRRcjUvd3ZQVW56cGFaN1RnR21yT21FaTlGQklOUnl6dk9rdDRWazZEaVU3RCtNYUJSdm5iNnR0VklPa2lDdFlhODRqenhlOFlFRUZGOElyTksrQm9yL28vdktxMVczSUxsU1VWWFd0N0hPWjV4TDBudHVTeGlBdW9ZK1Y0NEkzMXlPQkJ1T1AwMVpUek1TdGUvZCtIT1RRUEt2SGVGanF5Y0tpNGNTQUdZN3BobGs5eWJJem9hOTM0YldJOUFyRmF0WDY4UnkzTkF4cWNCbzh4ZklxZGZNN3Rlam02NldMT0Z6T3F6MDRrK1B0K0lXdWhOeS9CWEN2YXh2dk09In0="

Pour obtenir le reste des éléments de la table, exécutez une autre requête avec nextToken comme variable de requête. Continuez à inclure la variable nextToken jusqu'à ce que tous les éléments soient évalués.

Exemple de requête :

query MyQuery {
  listEmployees(nextToken:"eyJ......="){
    items {
      id
      name
      company
    }
    nextToken
  }
}

Indexer vos données

Dans l'exemple de requête suivant, l'expression de filtre est définie pour renvoyer un certain nombre d'éléments en fonction des employés égaux à AnyCompany :

query MyQuery {
  listEmployees(filter: {company: {eq: "AnyCompany"}}) {
    items {
      id
      name
      company
    }
    nextToken
  }
}

Pour répertorier tous les employés en fonction de leur entreprise, créez un index secondaire global pour le champ à interroger. Par exemple, dans Amplify, vous pouvez utiliser la directive @index pour définir des index secondaires :

type Employee @model{
  id:ID
  name : String
  email : AWSEmail
  company: String @index(name:"employeeByCompany", queryField: "listEmployeesByCompany")
}

Dans l'exemple de requête suivant, un index secondaire global employeeByCompany est défini pour le champ Entreprise. La requête est définie comme listEmployeesByCompany :

query MyQuery {
  listEmployeesByCompany(company: "AnyCompany") {
    items {
      id
      name
      company
    }
    nextToken
  }
}

Vous pouvez spécifier une variable de limite pour renvoyer un nombre souhaité d'éléments dans la base de données. Par exemple, dans la requête suivante, la variable de limite est définie sur 5 :

query MyQuery {
  listEmployeesByCompany(company: "AnyCompany",limit:5) {
    items {
      id
      name
      company
    }
    nextToken
  }
}

Remarque : la définition d'une variable de limite ne renvoie que le nombre souhaité d'éléments, même si vous avez appliqué des filterExpressions supplémentaires. Par exemple, dans la requête suivante, la variable de limite est définie sur 5 et le filtre est égal à Mary Major :

query MyQuery {
  listEmployeesByCompany(company: "AnyCompany",limit:5) {
    name:{
      eq:"Mary Major"
    }
  }) {
    items {
      id
      name
      company
    }
    nextToken
  }
}

La requête précédente renvoie seulement 5 éléments qui sont égaux à Mary Major. Cependant, il peut y avoir plus de 5 Mary Majors.

Remarque : les requêtes indexées renvoient également un maximum de 1 Mo de données à la fois. Pour les requêtes indexées plus importantes, vous pouvez utiliser la pagination.


AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 2 ans