Share via


Libreria client di Azure Cosmos DB per JavaScript - versione 4.0.0

/TypeScript

stato di compilazione della compilazione di npm più recente

Azure Cosmos DB è un servizio di database multimodello distribuito a livello globale che supporta database di documenti, con coppie chiave-valore, con colonne ampie e grafi. Questo pacchetto è destinato alle applicazioni JavaScript/TypeScript per interagire con i database API SQL e i documenti JSON che contengono:

  • Creare database di Cosmos DB e modificarne le impostazioni
  • Creare e modificare contenitori per archiviare le raccolte di documenti JSON
  • Creare, leggere, aggiornare ed eliminare gli elementi (documenti JSON) nei contenitori
  • Eseguire una query dei documenti nel database usando una sintassi di tipo SQL

Collegamenti principali:

Introduzione

Prerequisiti

Sottoscrizione di Azure e account API SQL di Cosmos DB

Per usare questo pacchetto, è necessario avere una sottoscrizione di Azure e un account di Cosmos DB (API SQL).

Se è necessario un account API SQL di Cosmos DB, è possibile usare Azure Cloud Shell per crearne uno con questo comando dell'interfaccia della riga di comando di Azure:

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

In alternativa, è possibile creare un account nel portale di Azure

NodeJS

Questo pacchetto viene distribuito tramite npm, preinstallato con NodeJS. È consigliabile usare Node 10 o versione successiva.

CORS

Per lo sviluppo per i browser, è necessario configurare regole CORS (Cross-Origin Resource Sharing) per l'account di Cosmos DB. Seguire le istruzioni nel documento collegato per creare nuove regole CORS per Cosmos DB.

Installare questo pacchetto

npm install @azure/cosmos

Ottenere le credenziali dell'account

Saranno necessari l'endpoint e la chiave dell'account di Cosmos DB. È possibile trovarli nel portale di Azure o usare il frammento dell'interfaccia della riga di comando di Azure qui sotto. Il frammento è presentato nel formato per la shell 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

Crea un'istanza di CosmosClient

L'interazione con Cosmos DB inizia con un'istanza della 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);
});

Per semplicità gli elementi key ed endpoint sono stati inclusi direttamente nel codice, ma è possibile caricarli da un file non presente nel controllo del codice sorgente usando un progetto come dotenv o caricandoli dalle variabili di ambiente

Negli ambienti di produzione i segreti come le chiavi devono essere archiviati in Azure Key Vault

Concetti chiave

Dopo aver inizializzato CosmosClient, è possibile interagire con i tipi di risorse primari in Cosmos DB:

  • Database: Un account di Cosmos DB può contenere più database. Quando si crea un database, si specifica l'API che si vuole usare quando si interagisce con questi documenti: SQL, MongoDB, Gremlin, Cassandra o Tabella di Azure. Usare l'oggetto Database per gestirne i contenitori.

  • Contenitore: Un contenitore è una raccolta di documenti JSON. Per creare (inserire), leggere, aggiornare ed eliminare elementi in un contenitore, è possibile usando i metodi sull'oggetto Container.

  • Articolo: Un elemento è un documento JSON archiviato in un contenitore. Ogni elemento deve includere una chiave id con un valore che identifica in modo univoco l'elemento all'interno del contenitore. Se non si specifica un id, l'SDK ne genererà uno automaticamente.

Per altre informazioni su queste risorse, vedere Usare database, contenitori ed elementi di Azure Cosmos.

Esempio

Le sezioni seguenti contengono diversi frammenti di codice relativi ad alcune delle attività più comuni di Cosmos DB:

Creazione di un database

Dopo aver autenticato CosmosClient, è possibile usare qualsiasi risorsa nell'account. Il frammento di codice seguente crea un database API NOSQL.

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

Creare un contenitore

Questo esempio crea un contenitore con impostazioni predefinite

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

Uso di chiavi di partizione

Questo esempio mostra vari tipi di chiavi di partizione supportate.

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 la chiave di partizione è costituita da un singolo valore, potrebbe essere fornita come valore letterale o una matrice.

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

Se la chiave di partizione è costituita da più valori, deve essere fornita come matrice.

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();

Inserire elementi

Per inserire elementi in un contenitore, passare un oggetto contenente i dati a Items.upsert. Il servizio Azure Cosmos DB richiede che ogni elemento disponga di una id chiave. Se non se ne specifica una, l'SDK genererà automaticamente un id.

Questo esempio inserisce diversi elementi nel contenitore

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);
}

Leggere un elemento

Per leggere un singolo elemento da un contenitore, usare Item.read. Si tratta di un'operazione meno costosa che usare SQL per eseguire una query in base a id.

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

CRUD sul contenitore con chiave di partizione gerarchica

Creare un contenitore con chiave di partizione gerarchica

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);

Inserire un elemento con chiave di partizione gerarchica definita come - ["/name", "/address/zip"]

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

Per leggere un singolo elemento da un contenitore con chiave di partizione gerarchica definita come - ["/name", "/address/zip"],

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

Eseguire una query su un elemento con chiave di partizione gerarchica con chiave di partizione gerarchica definita come - ["/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} `);
}

Eliminare un elemento

Per eliminare elementi da un contenitore, usare Item.delete.

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

Eseguire query sul database

Un database di API SQL Cosmos DB supporta l'esecuzione di query sugli elementi in un contenitore con Items.query usando una sintassi simile 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 `);
}

Eseguire query con parametri passando un oggetto contenente i parametri e i relativi valori a 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 `);
}

Per altre informazioni sull'esecuzione di query su database Cosmos DB tramite l'API SQL, vedere Eseguire query SQL sui dati di Azure Cosmos DB.

Modello pull del feed di modifiche

Il feed di modifiche può essere recuperato per una chiave di partizione, un intervallo di feed o un intero contenitore.

Per elaborare il feed di modifiche, creare un'istanza di ChangeFeedPullModelIterator. Quando si crea ChangeFeedPullModelIteratorinizialmente , è necessario specificare un valore obbligatorio changeFeedStartFrom all'interno ChangeFeedIteratorOptions del quale è costituita sia la posizione iniziale per la lettura delle modifiche che la risorsa(una chiave di partizione o un FeedRange) per cui le modifiche devono essere recuperate. Facoltativamente, è possibile usare maxItemCount in ChangeFeedIteratorOptions per impostare il numero massimo di elementi ricevuti per pagina.

Nota: se non changeFeedStartFrom viene specificato alcun valore, la modifica verrà recuperata per un intero contenitore da Now().

Per il feed di modifiche sono disponibili quattro posizioni iniziali:

  • 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);
}

Ecco un esempio di recupero del feed di modifiche per una chiave di partizione

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
}

Poiché il feed di modifiche è effettivamente un elenco infinito di elementi che include tutte le scritture e gli aggiornamenti futuri, il valore di hasMoreResults è sempre true. Quando si tenta di leggere il feed di modifiche e non sono disponibili nuove modifiche, viene ricevuta una risposta con NotModified stato.

Qui sono disponibili linee guida per l'utilizzo più dettagliate ed esempi di feed di modifiche.

Gestione degli errori

L'SDK genera diversi tipi di errori che possono verificarsi durante un'operazione.

  1. ErrorResponse viene generato se la risposta di un'operazione restituisce un codice di errore di >=400.
  2. TimeoutError viene generato se Abort viene chiamato internamente a causa del timeout.
  3. AbortError viene generata se un utente ha passato il segnale ha causato l'interruzione.
  4. RestError viene generata in caso di errore della chiamata di sistema sottostante a causa di problemi di rete.
  5. Errori generati da qualsiasi devDependencies. Per es. @azure/identity il pacchetto potrebbe generare un'eccezione CredentialUnavailableError.

Di seguito è riportato un esempio per la gestione degli errori di 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 gestire correttamente questi errori per garantire che l'applicazione possa eseguire correttamente il ripristino da eventuali errori e continuare a funzionare come previsto. Altre informazioni su alcuni di questi errori e sulle possibili soluzioni sono disponibili qui.

Risoluzione dei problemi

Generale

Quando si interagisce con Cosmos DB, gli errori restituiti dal servizio corrispondono agli stessi codici di stato HTTP restituiti per le richieste API REST:

Codici di stato HTTP per Azure Cosmos DB

Conflitti

Se ad esempio si prova a creare un elemento usando un id già in uso nel database Cosmos DB, viene restituito un errore 409 che indica il conflitto. Nel frammento di codice seguente, l'errore viene gestito normalmente rilevando l'eccezione e visualizzando informazioni aggiuntive sull'errore.

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");
  }
}

Transpile

Gli SDK di Azure sono progettati per supportare la sintassi ES5 JavaScript e le versioni LTS di Node.js. Se è necessario supporto per i runtime di JavaScript precedenti, ad esempio Internet Explorer o Node 6, sarà necessario eseguire il transpile del codice dell'SDK durante il processo di compilazione.

Gestire gli errori temporanei con nuovi tentativi

Mentre si usa Cosmos DB, potrebbero verificarsi errori temporanei causati dai limiti di frequenza applicati dal servizio o altri problemi temporanei come interruzioni della rete. Per informazioni sulla gestione di questi tipi di errori, vedere Modello di ripetizione dei tentativi nella guida Modelli di progettazione cloud e l'articolo correlato Modello a interruttore.

Registrazione

L'abilitazione della registrazione consente di individuare informazioni utili sugli errori. Per visualizzare un log di richieste e risposte HTTP, impostare la variabile di ambiente AZURE_LOG_LEVEL su info. In alternativa, la registrazione può essere abilitata in fase di esecuzione chiamando setLogLevel in @azure/logger. Durante l'uso AZURE_LOG_LEVEL di assicurarsi di impostarlo prima dell'inizializzazione della libreria di registrazione. In teoria, passarlo attraverso la riga di comando, se si usano librerie come dotenv assicurarsi che tali librerie vengano inizializzate prima della libreria di registrazione.

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

Per istruzioni più dettagliate su come abilitare i log, è possibile esaminare la documentazione del pacchetto di @azure/logger.

Diagnostica

La funzionalità Diagnostica Cosmos offre informazioni dettagliate avanzate su tutte le operazioni client. Un oggetto CosmosDiagnostics viene aggiunto alla risposta di tutte le operazioni client. ad esempio

  • Reponse dell'operazione di ricerca punto - item.read(), container.create(), database.delete()
  • Reponse dell'operazione di query -queryIterator.fetchAll(),
  • Operazioni bulk e batch -item.batch().
  • Oggetti di risposta di errore/eccezione.

Un oggetto CosmosDiagnostics viene aggiunto alla risposta di tutte le operazioni client. Sono disponibili 3 livelli di diagnostica Cosmos, informazioni, debug e debug-unsafe. Dove solo le informazioni sono destinate a sistemi di produzione e debug e debug-unsafe devono essere usate durante lo sviluppo e il debug, poiché utilizzano risorse notevolmente più elevate. Il livello di diagnostica Cosmos può essere impostato in 2 modi

  • A livello di codice
  const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
  • Uso delle variabili di ambiente. Il livello di diagnostica impostato dalla variabile di ambiente ha priorità più alta rispetto all'impostazione tramite le opzioni client.
  export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"

Cosmos Diagnostic ha tre membri

  • Tipo ClientSideRequestStatistics: contiene informazioni di diagnostica aggregate, tra cui ricerche di metadati, tentativi, endpoint contattati e statistiche di richiesta e risposta, ad esempio dimensioni e durata del payload. (viene sempre raccolto, può essere usato nei sistemi di produzione.

  • DiagnosticNode: struttura ad albero che acquisisce informazioni di diagnostica dettagliate. Simile alla har registrazione presente nei browser. Questa funzionalità è disabilitata per impostazione predefinita ed è destinata solo al debug di ambienti non di produzione. (raccolti a livello di diagnostica di debug e debug-unsafe)

  • ClientConfig: acquisisce informazioni essenziali correlate alle impostazioni di configurazione del client durante l'inizializzazione del client. (raccolti a livello di diagnostica di debug e debug-unsafe)

Assicurarsi di non impostare mai il livello debug-unsafe di diagnostica su nell'ambiente di produzione, poiché questo livello CosmosDiagnostics acquisisce payload di richiesta e risposta e se si sceglie di registrarlo (per impostazione predefinita registrato da @azure/logger a verbose livello). Questi payload potrebbero essere acquisiti nei sink di log.

Utilizzo della diagnostica

  • Poiché diagnostics viene aggiunto a tutti gli oggetti Response. È possibile accedere CosmosDiagnostic a livello di codice come indicato di seguito.
  // 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
  }
  • È anche possibile registrare diagnostics usando @azure/logger, la diagnostica viene sempre registrata usando @azure/logger a verbose livello . Pertanto, se si imposta il livello di diagnostica su debug o debug-unsafe e @azure/loggerverbosesu , diagnostics verrà registrato .

Passaggi successivi

Altro codice di esempio

Diversi esempi sono disponibili nel repository GitHub dell'SDK. Questi esempi offrono codice di esempio per altri scenari comuni correlati all'uso di Cosmos DB:

  • Operazioni sui database
  • Operazioni sui contenitori
  • Operazioni sugli elementi
  • Configurazione dell'indicizzazione
  • Lettura del feed di modifiche di un contenitore
  • Stored procedure
  • Modifica delle impostazioni di velocità effettiva di un database/contenitore
  • Operazioni di scrittura in più aree

Limitazioni

Attualmente le funzionalità seguenti non sono supportate. Per le opzioni alternative, vedere la sezione Soluzioni alternative di seguito.

Limitazioni del piano dati:

  • Query con COUNT da una sottoquery DISTINCT
  • Accesso diretto alla modalità TCP
  • Le query tra partizioni aggregate, ad esempio l'ordinamento, il conteggio e i valori distinct, non supportano i token di continuazione. Query streamable, ad esempio SELECT * FROM WHERE , supportare i token di continuazione. Vedere la sezione "Soluzione alternativa" per l'esecuzione di query non streamable senza un token di continuazione.
  • Feed di modifiche: Processore
  • Feed di modifiche: leggere più valori di chiave delle partizioni
  • Modello pull del feed di modifiche per tutte le versioni e modalità di eliminazione #27058
  • Supporto del modello pull del feed di modifiche per chiavi di partizione gerarchica parziale #27059
  • ORDER BY tra partizioni per tipi misti
  • Limitazioni del piano di controllo:

    • Ottenere le metriche CollectionSizeUsage, DatabaseUsage e DocumentUsage
    • Creare un indice geospaziale
    • Aggiornare la velocità effettiva con scalabilità automatica

    Soluzioni alternative

    Token di continuazione per query tra partizioni

    È possibile ottenere query tra partizioni con il supporto del token di continuazione usando il modello Side car. Questo modello può anche abilitare le applicazioni affinché siano composte da componenti e tecnologie eterogenei.

    Esecuzione di query tra partizioni non stremable

    Per eseguire query non streamable senza l'uso di token di continuazione, è possibile creare un iteratore di query con la specifica e le opzioni di query necessarie. Il codice di esempio seguente illustra come usare un iteratore di query per recuperare tutti i risultati senza la necessità di un token di continuazione:

    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
    }
    

    Questo approccio può essere usato anche per le query che possono essere sottoposte a flusso.

    Operazioni del piano di controllo

    In genere, è possibile usare il portale di Azure, l'API REST del provider di risorse di Azure Cosmos DB, l'interfaccia della riga di comando di Azure o PowerShell per il piano di controllo non supportato.

    Documentazione aggiuntiva

    Per una documentazione più completa sul servizio Cosmos DB, vedere la documentazione di Azure Cosmos DB su docs.microsoft.com.

    Contributo

    Per contribuire a questa libreria, leggere la guida ai contributi per altre informazioni su come compilare e testare il codice.

    Impression