Condividi tramite


Libreria client di Azure Cosmos DB per JavaScript - versione 4.2.0

/TypeScript

notifica npm più recente stato di compilazione

Azure Cosmos DB è un servizio di database multimodello distribuito a livello globale che supporta database document, key-value, wide-column e graph. Questo pacchetto è destinato alle applicazioni JavaScript/TypeScript per interagire con API SQL database e i documenti JSON che contengono:

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

Collegamenti chiave:

Introduttiva

Prerequisiti

Sottoscrizione di Azure e account API SQL di Cosmos DB

Per usare questo pacchetto, è necessario disporre di un sottoscrizione di Azuree di un account Cosmos DB (API SQL).

Se è necessario un account API SQL di Cosmos DB, è possibile usare l' 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 usando una versione LTS.

CORS

È necessario configurare regole cors (Cross-Origin Resource Sharing) per l'account Cosmos DB se è necessario sviluppare per i browser. 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

Sarà necessario l'endpoint dell'account cosmos DB e la chiave . È possibile trovarli nel portale di Azure o usare il frammento di codice dell'interfaccia della riga di comando di Azure di seguito. Il frammento di codice è formattato 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

Creare 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à, sono stati inclusi i key e endpoint direttamente nel codice, ma è probabile che si voglia caricarli da un file non nel controllo del codice sorgente usando un progetto come dotenv o il caricamento da variabili di ambiente

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

Concetti chiave

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

  • database: un account Cosmos DB può contenere più database. Quando si crea un database, si specifica l'API che si vuole usare durante l'interazione con i relativi documenti: SQL, MongoDB, Gremlin, Cassandra o Tabella di Azure. Utilizzare l'oggetto database per gestire i contenitori.

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

  • Item: 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à automaticamente uno.

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

Esempi

Le sezioni seguenti forniscono diversi frammenti di codice che illustrano alcune delle attività più comuni di Cosmos DB, tra cui:

Creare 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 delle 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, è possibile specificarla 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();

Inserisci 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 abbia una chiave id. Se non ne viene specificato uno, l'SDK genererà automaticamente un id.

In questo esempio vengono inseriti 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 rispetto all'uso di SQL per eseguire query id.

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

CRUD nel 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 API SQL di Cosmos DB supporta l'esecuzione di query sugli elementi in un contenitore con Items.query usando la 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 sui database Cosmos DB tramite l'API SQL, vedere Eseguire query sui dati di Azure Cosmos DB con query SQL.

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 inizialmente ChangeFeedPullModelIterator, è necessario specificare un valore changeFeedStartFrom obbligatorio all'interno del ChangeFeedIteratorOptions costituito sia dalla posizione iniziale per la lettura delle modifiche che dalla risorsa (una chiave di partizione o da un oggetto FeedRange) per cui devono essere recuperate le modifiche. Facoltativamente, è possibile usare maxItemCount in ChangeFeedIteratorOptions per impostare il numero massimo di elementi ricevuti per pagina.

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

Esistono quattro posizioni iniziali per il feed di modifiche:

  • 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 è in effetti 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, si riceve una risposta con NotModified stato.

Altre linee guida sull'utilizzo e esempi di feed di modifiche sono disponibili qui.

Gestione degli errori

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

  1. ErrorResponse viene generata se la risposta di un'operazione restituisce un codice di errore di >=400.
  2. TimeoutError viene generata se l'interruzione viene chiamata internamente a causa del timeout.
  3. AbortError viene generata se un utente ha passato un 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. Ad esempio, @azure/identity pacchetto potrebbe generare 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 gli errori di Cosmos DB restituiti dal servizio corrispondono agli stessi codici di stato HTTP restituiti per le richieste dell'API REST:

codici di stato HTTP per azure Cosmos DB

Conflitti

Ad esempio, se si tenta di creare un elemento usando un id già in uso nel database Cosmos DB, viene restituito un errore di 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");
  }
}

Transpiling

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

Gestire gli errori temporanei con tentativi

Durante l'uso di Cosmos DB, è possibile che si verifichino errori temporanei causati da limiti di frequenza applicati dal servizio o altri problemi temporanei, ad esempio interruzioni di rete. Per informazioni sulla gestione di questi tipi di errori, vedere modello di ripetizione dei tentativi nella guida Modelli di progettazione cloud e il modello di interruttore correlato.

Registrazione

L'abilitazione della registrazione può aiutare a 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 nel @azure/logger. Durante l'uso di AZURE_LOG_LEVEL assicurarsi di impostarlo prima dell'inizializzazione della libreria di registrazione. Idealmente 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 @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. come

  • 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 ai sistemi di produzione e il debug e debug-unsafe devono essere usate durante lo sviluppo e il debug, poiché utilizzano risorse significativamente più elevate. Il livello di diagnostica cosmos può essere impostato in due 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 simile ad albero che acquisisce informazioni di diagnostica dettagliate. Analogamente a har registrazione presente nei browser. Questa funzionalità è disabilitata per impostazione predefinita ed è destinata solo al debug di ambienti non di produzione. (raccolto a livello di diagnostica debug e debug-unsafe)

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

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

Utilizzo della diagnostica

  • Poiché diagnostics viene aggiunto a tutti gli oggetti Response. È possibile accedere a livello di codice CosmosDiagnostic 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 livello di verbose. Pertanto, se si imposta livello di diagnostica su debug o debug-unsafe e @azure/logger livello su verbose, verrà registrato diagnostics.

Passaggi successivi

Altro codice di esempio

sono disponibili diversi esempi nel repository GitHub dell'SDK. Questi esempi forniscono codice di esempio per scenari aggiuntivi comunemente rilevati durante l'uso di Cosmos DB:

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

Limitazioni

Attualmente le funzionalità seguenti sono non 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
  • Aggregare query tra partizioni, ad esempio l'ordinamento, il conteggio e i valori distinct, non supportano i token di continuazione. Query streamable, ad esempio SELECT * FROM WHERE , supporta 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
  • Supporto del modello pull 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 di scalabilità automatica

    Soluzioni alternative

    Token di continuazione per query tra partizioni

    È possibile ottenere query tra partizioni con il supporto del token di continuazione usando modello di auto lato. Questo modello può anche consentire alle applicazioni di essere 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 le opzioni e le specifiche 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 c.status, COUNT(c.id) AS count FROM c GROUP BY c.status",
    };
    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 streamable.

    Operazioni del piano di controllo

    In genere, è possibile usare portale di Azure, l'API REST del provider di risorse di Azure Cosmos DB, dell'interfaccia della riga di comando di Azure o powerShell per le limitazioni non supportate del piano di controllo.

    Documentazione aggiuntiva

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

    Contribuire

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

    impressioni