Share via


Biblioteca de cliente do Azure Cosmos DB para JavaScript – versão 4.0.0

/TypeScript

mais recente npm badgeBuild Status (Estado da Compilação do distintivo npm mais recente)

O Azure Cosmos DB é um serviço de base de dados com vários modelos distribuído globalmente que suporta bases de dados de documento, chave-valor, colunas e grafo. Este pacote destina-se a que as aplicações JavaScript/TypeScript interajam com bases de dados da API SQL e os documentos JSON que contêm:

  • Criar bases de dados do Cosmos DB e modificar as respetivas definições
  • Criar e modificar contentores para armazenar coleções de documentos JSON
  • Criar, ler, atualizar e eliminar os itens (documentos JSON) nos seus contentores
  • Consultar os documentos na base de dados com a sintaxe semelhante a SQL

Ligações principais:

Introdução

Pré-requisitos

Subscrição do Azure e Conta da API SQL do Cosmos DB

Tem de ter uma Subscrição do Azure e uma conta do Cosmos DB (API SQL) para utilizar este pacote.

Se precisar de uma conta da API SQL do Cosmos DB, pode utilizar a Cloud Shell do Azure para criar uma com este comando da CLI do Azure:

az cosmosdb create --resource-group <resource-group-name> --name <cosmos-database-account-name>

Em alternativa, pode criar uma conta no Portal do Azure

NodeJS

Este pacote é distribuído através do npm , que vem pré-instalado com o NodeJS. Deve utilizar o Nó v10 ou superior.

CORS

Se precisar de desenvolver para browsers, tem de configurar regras de Partilha de Recursos Entre Origens (CORS) para a sua conta do Cosmos DB. Siga as instruções no documento ligado para criar novas regras CORS para o Cosmos DB.

Instalar este pacote

npm install @azure/cosmos

Obter Credenciais de Conta

Precisará do ponto final e da chave da conta do Cosmos DB. Pode encontrá-los no Portal do Azure ou utilizar o fragmento da CLI do Azure abaixo. O fragmento está formatado para a shell do Bash.

az cosmosdb show --resource-group <your-resource-group> --name <your-account-name> --query documentEndpoint --output tsv
az cosmosdb keys list --resource-group <your-resource-group> --name <your-account-name> --query primaryMasterKey --output tsv

Criar uma instância de CosmosClient

A interação com o Cosmos DB começa com uma instância da classe CosmosClient

const { CosmosClient } = require("@azure/cosmos");

const endpoint = "https://your-account.documents.azure.com";
const key = "<database account masterkey>";
const client = new CosmosClient({ endpoint, key });

async function main() {
  // The rest of the README samples are designed to be pasted into this function body
}

main().catch((error) => {
  console.error(error);
});

Para simplificar, incluímos o key e endpoint diretamente no código, mas é provável que queira carregá-los a partir de um ficheiro que não esteja no controlo de origem através de um projeto, como dotenv ou carregamento a partir de variáveis de ambiente

Em ambientes de produção, segredos como chaves devem ser armazenados no Azure Key Vault

Conceitos-chave

Depois de inicializar um CosmosClient, pode interagir com os tipos de recursos principais no Cosmos DB:

  • Base de dados: uma conta do Cosmos DB pode conter várias bases de dados. Quando cria uma base de dados, especifica a API que pretende utilizar ao interagir com os respetivos documentos: SQL, MongoDB, Gremlin, Cassandra ou Tabela do Azure. Utilize o objeto Base de Dados para gerir os respetivos contentores.

  • Contentor: um contentor é uma coleção de documentos JSON. Pode criar (inserir), ler, atualizar e eliminar itens num contentor com métodos no objeto Contentor .

  • Item: um Item é um documento JSON armazenado num contentor. Cada Item tem de incluir uma id chave com um valor que identifique exclusivamente o item no contentor. Se não fornecer um id, o SDK irá gerar um automaticamente.

Para obter mais informações sobre estes recursos, veja Trabalhar com bases de dados, contentores e itens do Azure Cosmos.

Exemplos

As secções seguintes fornecem vários fragmentos de código que abrangem algumas das tarefas mais comuns do Cosmos DB, incluindo:

Criar uma base de dados

Depois de autenticar o CosmosClient, pode trabalhar com qualquer recurso na conta. O fragmento de código abaixo cria uma base de dados da API NOSQL.

const { database } = await client.databases.createIfNotExists({ id: "Test Database" });
console.log(database.id);

Criar um contentor

Este exemplo cria um contentor com predefinições

const { container } = await database.containers.createIfNotExists({ id: "Test Database" });
console.log(container.id);

Utilizar Chaves de Partição

Este exemplo mostra vários tipos de Chaves de partição suportadas.

await container.item("id", "1").read();        // string type
await container.item("id", 2).read();          // number type
await container.item("id", true).read();       // boolean type
await container.item("id", {}).read();         // None type
await container.item("id", undefined).read();  // None type
await container.item("id", null).read();       // null type

Se a Chave de Partição for constituída por um único valor, pode ser fornecida como um valor literal ou uma matriz.

await container.item("id", "1").read();
await container.item("id", ["1"]).read();

Se a Chave de Partição for constituída por mais de um valor, deve ser fornecida como uma matriz.

await container.item("id", ["a", "b"]).read();
await container.item("id", ["a", 2]).read();
await container.item("id", [{}, {}]).read();
await container.item("id", ["a", {}]).read();
await container.item("id", [2, null]).read();

Inserir itens

Para inserir itens num contentor, transmita um objeto que contenha os seus dados para Items.upsert. O serviço Azure Cosmos DB requer que cada item tenha uma id chave. Se não fornecer um, o SDK irá gerar um id automaticamente.

Este exemplo insere vários itens no contentor

const cities = [
  { id: "1", name: "Olympia", state: "WA", isCapitol: true },
  { id: "2", name: "Redmond", state: "WA", isCapitol: false },
  { id: "3", name: "Chicago", state: "IL", isCapitol: false }
];
for (const city of cities) {
  await container.items.create(city);
}

Ler um item

Para ler um único item a partir de um contentor, utilize Item.read. Esta é uma operação menos dispendiosa do que a utilização do SQL para consultar por id.

await container.item("1", "1").read();

CRUD no Contentor com chave de partição hierárquica

Criar um Contentor com chave de partição hierárquica

const containerDefinition = {
  id: "Test Database",
  partitionKey: {
    paths: ["/name", "/address/zip"],
    version: PartitionKeyDefinitionVersion.V2,
    kind: PartitionKeyKind.MultiHash,
  },
}
const { container } = await database.containers.createIfNotExists(containerDefinition);
console.log(container.id);

Inserir um item com a chave de partição hierárquica definida como - ["/name", "/address/zip"]

const item = {
  id: 1,
  name: 'foo',
  address: {
    zip: 100
  },
  active: true
}
await container.items.create(item);

Para ler um único item a partir de um contentor com a chave de partição hierárquica definida como - ["/name", "/address/zip"],

await container.item("1", ["foo", 100]).read();

Consultar um item com chave de partição hierárquica com a chave de partição hierárquica definida como - ["/name", "/address/zip"],

const { resources } = await container.items
  .query("SELECT * from c WHERE c.active = true", {
          partitionKey: ["foo", 100],
        })
  .fetchAll();
for (const item of resources) {
  console.log(`${item.name}, ${item.address.zip} `);
}

Eliminar um item

Para eliminar itens de um contentor, utilize Item.delete.

// Delete the first item returned by the query above
await container.item("1").delete();

Consultar a base de dados

Uma base de dados da API SQL do Cosmos DB suporta a consulta dos itens num contentor com Items.query com sintaxe semelhante a SQL:

const { resources } = await container.items
  .query("SELECT * from c WHERE c.isCapitol = true")
  .fetchAll();
for (const city of resources) {
  console.log(`${city.name}, ${city.state} is a capitol `);
}

Execute consultas parametrizadas ao transmitir um objeto que contém os parâmetros e os respetivos valores para Items.query:

const { resources } = await container.items
  .query({
    query: "SELECT * from c WHERE c.isCapitol = @isCapitol",
    parameters: [{ name: "@isCapitol", value: true }]
  })
  .fetchAll();
for (const city of resources) {
  console.log(`${city.name}, ${city.state} is a capitol `);
}

Para obter mais informações sobre como consultar bases de dados do Cosmos DB com a API SQL, veja Consultar dados do Azure Cosmos DB com consultas SQL.

Modelo Pull do Feed de Alterações

O feed de alterações pode ser obtido para uma chave de partição, um intervalo de feed ou um contentor inteiro.

Para processar o feed de alterações, crie uma instância de ChangeFeedPullModelIterator. Quando criar ChangeFeedPullModelIteratorinicialmente , tem de especificar um valor necessário changeFeedStartFrom dentro do ChangeFeedIteratorOptions que consiste tanto na posição inicial para as alterações de leitura como no recurso (uma chave de partição ou um FeedRange) para o qual as alterações devem ser obtidas. Opcionalmente, pode utilizar maxItemCount no ChangeFeedIteratorOptions para definir o número máximo de itens recebidos por página.

Nota: se não for especificado nenhum changeFeedStartFrom valor, o changefeed será obtido para um contentor inteiro a partir de Agora().

Existem quatro posições iniciais para o feed de alterações:

  • Beginning
// Signals the iterator to read changefeed from the beginning of time.
const options = {
  changeFeedStartFrom: ChangeFeedStartFrom.Beginning();
}
const iterator = container.getChangeFeedIterator(options);
  • Time
// Signals the iterator to read changefeed from a particular point of time.
const time = new Date("2023/09/11") // some sample date
const options = {
  changeFeedStartFrom: ChangeFeedStartFrom.Time(time);
}
  • Now
// Signals the iterator to read changefeed from this moment onward.
const options = {
  changeFeedStartFrom: ChangeFeedStartFrom.Now();
}
  • Continuation
// Signals the iterator to read changefeed from a saved point.
const continuationToken = "some continuation token recieved from previous request";
const options = {
  changeFeedStartFrom: ChangeFeedStartFrom.Continuation(continuationToken);
}

Eis um exemplo de obtenção de feed de alterações para uma chave de partição

const partitionKey = "some-partition-Key-value";
const options = {
  changeFeedStartFrom: ChangeFeedStartFrom.Beginning(partitionKey),
};

const iterator = container.items.getChangeFeedIterator(options);

while (iterator.hasMoreResults) {
  const response = await iterator.readNext();
  // process this response
}

Uma vez que o feed de alterações é efetivamente uma lista infinita de itens que abrange todas as futuras escritas e atualizações, o valor de hasMoreResults é sempre true. Quando tenta ler o feed de alterações e não existem novas alterações disponíveis, recebe uma resposta com NotModified o estado.

Pode encontrar diretrizes de utilização mais detalhadas e exemplos de feed de alterações aqui.

Processamento de Erros

O SDK gera vários tipos de erros que podem ocorrer durante uma operação.

  1. ErrorResponse é emitida se a resposta de uma operação devolver um código de erro de >=400.
  2. TimeoutError é emitido se Abort for chamado internamente devido ao tempo limite.
  3. AbortError é emitida se algum utilizador tiver transmitido o sinal que causou o abortar.
  4. RestError é emitida em caso de falha da chamada do sistema subjacente devido a problemas de rede.
  5. Erros gerados por quaisquer devDependencies. Por exemplo, @azure/identity O pacote pode emitir CredentialUnavailableError.

Segue-se um exemplo para processar erros do tipo ErrorResponse, TimeoutError, AbortErrore RestError.

try {
  // some code
} catch (err) {
  if (err instanceof ErrorResponse) {
    // some specific error handling.
  } else if (err instanceof RestError) {
    // some specific error handling.
  }
  // handle other type of errors in similar way.
  else {
    // for any other error.
  }
}

É importante lidar corretamente com estes erros para garantir que a aplicação pode recuperar corretamente de quaisquer falhas e continuar a funcionar conforme esperado. Pode encontrar mais detalhes sobre alguns destes erros e as suas possíveis soluções aqui.

Resolução de problemas

Geral

Quando interage com erros do Cosmos DB devolvidos pelo serviço, correspondem aos mesmos códigos de estado HTTP devolvidos para pedidos da API REST:

Códigos de Estado HTTP para o Azure Cosmos DB

Conflitos

Por exemplo, se tentar criar um item com um id que já está a ser utilizado na base de dados do Cosmos DB, é devolvido um 409 erro que indica o conflito. No fragmento seguinte, o erro é processado corretamente através da deteção da exceção e da apresentação de informações adicionais sobre o erro.

try {
  await containers.items.create({ id: "existing-item-id" });
} catch (error) {
  if (error.code === 409) {
    console.log("There was a conflict with an existing item");
  }
}

Transpiling

Os SDKs do Azure foram concebidos para suportar a sintaxe JavaScript ES5 e as versões LTS do Node.js. Se precisar de suporte para runtimes javaScript anteriores, como o Internet Explorer ou o Node 6, terá de transpor o código do SDK como parte do processo de compilação.

Lidar com erros transitórios com repetições

Ao trabalhar com o Cosmos DB, poderá deparar-se com falhas transitórias causadas por limites de taxa impostos pelo serviço ou outros problemas transitórios, como falhas de rede. Para obter informações sobre como lidar com estes tipos de falhas, veja Padrão de repetição no guia Padrões de Conceção da Cloud e o padrão de Disjuntor Automático relacionado.

Registo

Ativar o registo pode ajudar a descobrir informações úteis sobre falhas. Para ver um registo de pedidos e respostas HTTP, defina a variável de AZURE_LOG_LEVEL ambiente como info. Em alternativa, o registo pode ser ativado no runtime ao chamar setLogLevel no @azure/logger. Ao utilizar AZURE_LOG_LEVEL , certifique-se de que a define antes de a biblioteca de registos ser inicializada. Idealmente, transmita-a através da linha de comandos, se estiver a utilizar bibliotecas como, por dotenv exemplo, certifique-se de que essas bibliotecas são inicializadas antes da biblioteca de registos.

const { setLogLevel } = require("@azure/logger");
setLogLevel("info");

Para obter instruções mais detalhadas sobre como ativar os registos, pode ver os documentos do pacote @azure/logger.

Diagnóstico

A funcionalidade Diagnóstico do Cosmos fornece informações melhoradas sobre todas as operações do cliente. É adicionado um objeto CosmosDiagnostics à resposta de todas as operações de cliente. como, por exemplo,

  • Reponse da operação de pesquisa de pontos - item.read(), container.create(), database.delete()
  • Reponse da operação de consulta -queryIterator.fetchAll(),
  • Operações em massa e batch -item.batch().
  • Erro/Objetos de resposta de exceção.

É adicionado um objeto CosmosDiagnostics à resposta de todas as operações de cliente. Existem três níveis de Diagnóstico do Cosmos, informações, depuração e depuração não seguras. Quando apenas as informações se destinam a sistemas de produção, a depuração e depuração não segura devem ser utilizadas durante o desenvolvimento e a depuração, uma vez que consomem recursos significativamente mais elevados. O nível de Diagnóstico do Cosmos pode ser definido de 2 formas

  • Programaticamente
  const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
  • Utilizar variáveis de ambiente. (O nível de diagnóstico definido pela variável De ambiente tem maior prioridade em definir o nível através das opções de cliente.)
  export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"

O Diagnóstico do Cosmos tem três membros

  • Tipo ClientSideRequestStatistics: contém detalhes de diagnóstico agregados, incluindo pesquisas de metadados, repetições, pontos finais contactados e estatísticas de pedidos e respostas, como o tamanho e a duração do payload. (é sempre recolhido, pode ser utilizado em sistemas de produção.)

  • DiagnosticNode: é uma estrutura semelhante a uma árvore que captura informações de diagnóstico detalhadas. Semelhante à har gravação presente nos browsers. Esta funcionalidade está desativada por predefinição e destina-se apenas à depuração de ambientes de não produção. (recolhido ao nível do diagnóstico de depuração e depuração não segura)

  • ClientConfig: captura informações essenciais relacionadas com as definições de configuração do cliente durante a inicialização do cliente. (recolhido ao nível do diagnóstico de depuração e depuração não segura)

Certifique-se de que nunca define o nível de diagnóstico como debug-unsafe no ambiente de produção, uma vez que este nível CosmosDiagnostics captura payloads de pedidos e respostas e se optar por registem-no (é registado por predefinição @azure/logger ao verbose nível). Estes payloads podem ser capturados nos sinks de registo.

Consumo de Diagnósticos

  • Uma vez diagnostics que é adicionado a todos os objetos de Resposta. Pode aceder CosmosDiagnostic programaticamente da seguinte forma.
  // For point look up operations
  const { container, diagnostics: containerCreateDiagnostic } =
    await database.containers.createIfNotExists({
      id: containerId,
      partitionKey: {
        paths: ["/key1"],
      },
  });

  // For Batch operations
   const operations: OperationInput[] = [
    {
      operationType: BulkOperationType.Create,
      resourceBody: { id: 'A', key: "A", school: "high" },
    },
  ];
  const response = await container.items.batch(operations, "A"); 
  
  // For query operations
  const queryIterator = container.items.query("select * from c");
  const { resources, diagnostics } = await queryIterator.fetchAll();

  // While error handling
  try {
    // Some operation that might fail
  } catch (err) {
    const diagnostics = err.diagnostics
  }
  • Também pode iniciar sessão diagnostics com @azure/loggero , o diagnóstico é sempre registado ao @azure/loggerverbose nível. Por isso, se definir o Nível de diagnóstico como debug ou debug-unsafe e @azure/logger o nível como verbose, diagnostics será registado.

Passos seguintes

Mais código de exemplo

Estão disponíveis vários exemplos no repositório do GitHub do SDK. Estes exemplos fornecem código de exemplo para cenários adicionais normalmente encontrados ao trabalhar com o Cosmos DB:

  • Operações da Base de Dados
  • Operações de Contentor
  • Operações de Itens
  • Configurar Indexação
  • Ler um Feed de Alterações de contentor
  • Procedimentos Armazenados
  • Alterar as definições de débito da Base de Dados/Contentor
  • Operações de Escrita de Várias Regiões

Limitações

Atualmente, as funcionalidades abaixo não são suportadas. Para obter opções alternativas, consulte a secção Soluções abaixo.

Limitações do Plano de Dados:

  • Consultas com CONTAR de uma subconsulta DISTINCT
  • Acesso direto ao Modo TCP
  • As consultas entre partições agregadas, como a ordenação, a contagem e a distinção, não suportam tokens de continuação. Consultas passíveis de transmissão em fluxo, como SELECT * FROM WHERE , suporte tokens de continuação. Veja a secção "Solução" para executar consultas não passíveis de transmissão em fluxo sem um token de continuação.
  • Feed de Alterações: Processador
  • Feed de Alterações: ler vários valores de chave de partições
  • Alterar o modelo de solicitação do Feed todas as versões e o modo de eliminação #27058
  • Suporte do modelo de solicitação do Feed de Alterações para chaves de partição hierárquicas parciais #27059
  • ORDEM POR entre partições para tipos mistos
  • Limitações do Plano de Controlo:

    • Obter métricas CollectionSizeUsage, DatabaseUsage e DocumentUsage
    • Criar Índice Geoespacial
    • Atualizar débito do Dimensionamento Automático

    Soluções

    Token de continuação para consultas entre partições

    Pode obter consultas entre partições com suporte de tokens de continuação através do padrão side car. Este padrão também pode ativar as aplicações a ser compostas por componentes heterogéneos e tecnologias.

    Executar uma consulta entre partições não stremable

    Para executar consultas não passíveis de transmissão em fluxo sem a utilização de tokens de continuação, pode criar um iterador de consultas com as especificações e opções de consulta necessárias. O código de exemplo seguinte demonstra como utilizar um iterador de consultas para obter todos os resultados sem a necessidade de um token de continuação:

    const querySpec = {
      query: "SELECT * FROM c WHERE c.status = @status",
      parameters: [{ name: "@status", value: "active" }],
    };
    const queryOptions = {
      maxItemCount: 10, // maximum number of items to return per page
      enableCrossPartitionQuery: true,
    };
    const querIterator = await container.items.query(querySpec, queryOptions);
    while (querIterator.hasMoreResults()) {
      const { resources: result } = await querIterator.fetchNext();
      //Do something with result
    }
    

    Esta abordagem também pode ser utilizada para consultas passíveis de transmissão em fluxo.

    Operações do Plano de Controlo

    Normalmente, pode utilizar o Portal do Azure, a API REST do Fornecedor de Recursos do Azure Cosmos DB, a CLI do Azure ou o PowerShell para as limitações não suportadas do plano de controlo.

    Documentação adicional

    Para obter documentação mais extensa sobre o serviço Cosmos DB, veja a documentação do Azure Cosmos DB sobre docs.microsoft.com.

    Contribuir

    Se quiser contribuir para esta biblioteca, leia o guia de contribuição para saber mais sobre como criar e testar o código.

    Impressões