Por que minhas consultas de lista estão retornando o número errado de itens quando uso o DynamoDB com o AWS AppSync?

Data da última atualização: 22/06/2022

Minhas consultas de lista estão retornando o número errado de itens quando uso o Amazon DynamoDB com o AWS AppSync. Como resolvo isso?

Breve descrição

Quando você usa uma consulta de lista com o AWS AppSync e o Amazon DynamoDB, o DynamoDB executa uma operação de varredura na tabela e retorna um determinado número de itens avaliados. Se você fornecer uma operação FilterExpression na solicitação, o DynamoDB aplicará a FilterExpression somente a esses itens avaliados.

O número de itens que a varredura verifica depende da variável limite que você aplicou à consulta. Se nenhum limite for aplicado, o DynamoDB usará o limite padrão configurado no modelo de mapeamento de solicitações. A varredura retorna somente os itens que são avaliados e correspondem à expressão do filtro. Para retornar o número esperado de itens, você deve ajustar a variável limite.

Você pode aumentar o limite padrão no seu modelo de mapeamento ou adicionar uma variável limite à consulta de lista do GraphQL. No entanto, o número máximo de itens que você pode avaliar é de 1 MB. Se a operação de varredura exceder 1 MB de dados, você poderá usar a paginação para obter o restante dos dados. Para ajudá-lo a consultar um banco de dados que tenha milhares de itens, você pode indexar seus dados para filtrar os resultados por um campo comum.

Resolução

Aumentar o limite padrão

No exemplo de modelo de mapeamento a seguir para uma API gerada pelo AWS Amplify, o limite padrão é 100:

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

Para avaliar mais itens, altere o limite padrão no modelo de mapeamento. Ou adicione uma variável limite à consulta de lista. Por exemplo, na consulta de lista a seguir, o limite é definido como 1000:

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

Paginar com o AWS AppSync

Para paginar com o AWS AppSync, adicione um argumento nextToken à sua consulta do GraphQL.

Consulta de exemplo:

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

Observação: o valor nextToken que a consulta retorna é null ou uma string longa que começa com ey e termina com =. Esse valor representa a última chave avaliada. Se o valor for null, não haverá mais itens na tabela para avaliar. Se for uma string longa, então há mais itens para avaliar.

Por exemplo:

"nextToken": "eyJ2ZXJzaW9uIjoyLCJ0b2tlbiI6IkFRSUNBSGg5OUIvN3BjWU41eE96NDZJMW5GeGM4WUNGeG1acmFOMUpqajZLWkFDQ25BRkQxUjREaVVxMkd1aDZNZ2ZTMmhPMUFBQUNIVENDQWhrR0NTcUdTSWIzRFFFSEJxQ0NBZ293Z2dJR0FnRUFNSUlCL3dZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF4c0RFY1ZZUGpaRDFxbDcxNENBUkNBZ2dIUWkwaGtJYytoU04vRFMzL3VQT2ZDMnpIV1dBVkg4LzU3TWFwMGZWSHVackt1VmV4emRvTVQrNml6VC9RdDRsSVNGN1pmc3NWTHVvcnJpRE1RZVE5ckNyd3J4dmNOY3ZZUzhTc21PRFFkaTUreVhQcDJ1OENaK29Sd2wrV3VoOGJ0YlBpQXQydjRNdmw2L09jRzRHV2RxRmFjeTFDRjRyK2FPd29velRTV3NqMTd4OUpwVi93cHVYc2tTN2R5TmYxa3JJS3hSL3BMWlY5M3JPSlVocEpDV2xEL3Y1UU5JdGJoOWpyaTI3N09LbUZsVlh3bDRna3hDa1kzeGZMNjZrM2dZY0hpbHlUOE1GUnBLU0VCTFE3RGEzSlJtUG8xUkJvQ051K3dBTkwwd09Vckp0N1BFb0QvTVRrenZDV1lCTXhVaUhaRDdrM3Y5a2FJS2NScHY0ajhuTDJ2Nk9EZ3plTjgwN1RtRFViM21rRUsrakRRcjUvd3ZQVW56cGFaN1RnR21yT21FaTlGQklOUnl6dk9rdDRWazZEaVU3RCtNYUJSdm5iNnR0VklPa2lDdFlhODRqenhlOFlFRUZGOElyTksrQm9yL28vdktxMVczSUxsU1VWWFd0N0hPWjV4TDBudHVTeGlBdW9ZK1Y0NEkzMXlPQkJ1T1AwMVpUek1TdGUvZCtIT1RRUEt2SGVGanF5Y0tpNGNTQUdZN3BobGs5eWJJem9hOTM0YldJOUFyRmF0WDY4UnkzTkF4cWNCbzh4ZklxZGZNN3Rlam02NldMT0Z6T3F6MDRrK1B0K0lXdWhOeS9CWEN2YXh2dk09In0="

Para obter o restante dos itens na tabela, execute outra consulta com nextToken como uma variável de consulta. Continue a incluir a variável nexToken até que todos os itens sejam avaliados.

Consulta de exemplo:

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

Indexe seus dados

No exemplo de consulta a seguir, a expressão de filtro é definida para retornar um número de itens baseados em funcionários iguais a AnyCompany:

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

Para listar todos os funcionários com base em sua empresa, crie um índice secundário global para o campo a ser consultado. Por exemplo, no Amplify, você pode usar a diretiva @index para definir índices secundários:

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

No exemplo de consulta a seguir, uma GSI employeeByCompany é definida no campo company (empresa) e a consulta é definida como listEmployeesByCompany:

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

Você pode especificar uma variável limite para retornar um número pretendido de itens no banco de dados. Por exemplo, na consulta a seguir, a variável limite é definida como 5:

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

Observação: a definição de uma variável limite retorna somente o número pretendido de itens, mesmo que você tenha aplicado FilterExpressions adicionais. Por exemplo, na consulta a seguir, a variável limite é definida como 5 e o filtro é igual a Mary Major:

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

A consulta anterior retorna somente 5 itens que são iguais a Mary Major. No entanto, pode haver mais de 5 Mary Majors.

Observação: as consultas indexadas também retornam no máximo 1 MB de dados por vez. Para consultas indexadas maiores, você pode usar a paginação.


Esse artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?