Partager via


Bibliothèque de client Azure Cosmos DB pour JavaScript - version 4.2.0

/Tapuscrit

dernier badge npm État de build

Azure Cosmos DB est un service de base de données multimodèle distribué à l’échelle mondiale qui prend en charge les bases de données document, clé-valeur, large et graphique. Ce package est destiné aux applications JavaScript/TypeScript pour interagir avec 'API SQL bases de données et les documents JSON qu’ils contiennent :

  • Créer des bases de données Cosmos DB et modifier leurs paramètres
  • Créer et modifier des conteneurs pour stocker des collections de documents JSON
  • Créer, lire, mettre à jour et supprimer les éléments (documents JSON) dans vos conteneurs
  • Interroger les documents dans votre base de données à l’aide de la syntaxe de type SQL

Liens clés :

  • package (npm)
  • Documentation de référence de l’API
  • documentation produit

Commencer

Conditions préalables

Abonnement Azure et compte d’API SQL Cosmos DB

Vous devez disposer d’un abonnement Azure et d’un compte Cosmos DB (API SQL) pour utiliser ce package.

Si vous avez besoin d’un compte d’API SQL Cosmos DB, vous pouvez utiliser Azure Cloud Shell pour en créer un avec cette commande Azure CLI :

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

Vous pouvez également créer un compte dans le portail Azure

NodeJS

Ce package est distribué via npm qui est préinstallé avec NodeJS à l’aide d’une version LTS.

CORS

Vous devez configurer règles de partage de ressources cross-origin (CORS) pour votre compte Cosmos DB si vous devez développer pour les navigateurs. Suivez les instructions du document lié pour créer de nouvelles règles CORS pour votre Cosmos DB.

Installer ce package

npm install @azure/cosmos

Obtenir les informations d’identification du compte

Vous aurez besoin de votre point de terminaison de compte Cosmos DB et de clé . Vous pouvez les trouver dans le portail Azure ou utiliser l’extrait de code Azure CLI ci-dessous. L’extrait de code est mis en forme pour l’interpréteur de commandes 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

Créer une instance de CosmosClient

L’interaction avec Cosmos DB commence par une instance de la 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);
});

Par souci de simplicité, nous avons inclus les key et les endpoint directement dans le code, mais vous voudrez probablement les charger à partir d’un fichier non dans le contrôle de code source à l’aide d’un projet tel que dotenv ou le chargement à partir de variables d’environnement

Dans les environnements de production, les secrets tels que les clés doivent être stockés dans azure Key Vault

Concepts clés

Une fois que vous avez initialisé un CosmosClient, vous pouvez interagir avec les types de ressources principaux dans Cosmos DB :

  • base de données: un compte Cosmos DB peut contenir plusieurs bases de données. Lorsque vous créez une base de données, vous spécifiez l’API que vous souhaitez utiliser lors de l’interaction avec ses documents : SQL, MongoDB, Gremlin, Cassandra ou Table Azure. Utilisez l’objet base de données pour gérer ses conteneurs.

  • Container: un conteneur est une collection de documents JSON. Vous créez (insertion), lisez, mettez à jour et supprimez des éléments dans un conteneur à l’aide de méthodes sur l’objet Container.

  • Élément: un élément est un document JSON stocké dans un conteneur. Chaque élément doit inclure une clé id avec une valeur qui identifie de façon unique l’élément dans le conteneur. Si vous ne fournissez pas de id, le Kit de développement logiciel (SDK) en génère automatiquement un.

Pour plus d’informations sur ces ressources, consultez Utilisation de bases de données, de conteneurs et d’éléments Azure Cosmos.

Exemples

Les sections suivantes fournissent plusieurs extraits de code couvrant certaines des tâches Cosmos DB les plus courantes, notamment :

Créer une base de données

Après avoir authentifié votre CosmosClient, vous pouvez utiliser n’importe quelle ressource dans le compte. L’extrait de code ci-dessous crée une base de données d’API NOSQL.

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

Créer un conteneur

Cet exemple crée un conteneur avec les paramètres par défaut

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

Utilisation des clés de partition

Cet exemple montre différents types de clés de partition prises en charge.

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

Si la clé de partition se compose d’une valeur unique, elle peut être fournie en tant que valeur littérale ou tableau.

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

Si la clé de partition se compose de plusieurs valeurs, elle doit être fournie en tant que tableau.

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

Insérer des éléments

Pour insérer des éléments dans un conteneur, transmettez un objet contenant vos données à Items.upsert. Le service Azure Cosmos DB nécessite que chaque élément dispose d’une clé id. Si vous n’en fournissez pas, le Kit de développement logiciel (SDK) génère automatiquement une id.

Cet exemple insère plusieurs éléments dans le conteneur

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

Lire un élément

Pour lire un élément unique à partir d’un conteneur, utilisez Item.read. Il s’agit d’une opération moins coûteuse que l’utilisation de SQL pour interroger par id.

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

CRUD sur conteneur avec une clé de partition hiérarchique

Créer un conteneur avec une clé de partition hiérarchique

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

Insérer un élément avec une clé de partition hiérarchique définie comme - ["/name", "/address/zip"]

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

Pour lire un élément unique à partir d’un conteneur avec une clé de partition hiérarchique définie comme - ["/name", "/address/zip"],

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

Interroger un élément avec une clé de partition hiérarchique avec une clé de partition hiérarchique définie comme - ["/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} `);
}

Supprimer un élément

Pour supprimer des éléments d’un conteneur, utilisez Item.delete.

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

Interroger la base de données

Une base de données d’API SQL Cosmos DB prend en charge l’interrogation des éléments d’un conteneur avec Items.query à l’aide de la syntaxe de type 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 `);
}

Effectuez des requêtes paramétrables en transmettant un objet contenant les paramètres et leurs valeurs à 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 `);
}

Pour plus d’informations sur l’interrogation de bases de données Cosmos DB à l’aide de l’API SQL, consultez Interroger des données Azure Cosmos DB avec des requêtes SQL.

Modèle d’extraction de flux de modification

Le flux de modification peut être récupéré pour une clé de partition, une plage de flux ou un conteneur entier.

Pour traiter le flux de modification, créez une instance de ChangeFeedPullModelIterator. Lorsque vous créez initialement ChangeFeedPullModelIterator, vous devez spécifier une valeur de changeFeedStartFrom requise à l’intérieur de l'ChangeFeedIteratorOptions qui se compose à la fois de la position de départ pour la lecture des modifications et de la ressource (une clé de partition ou un FeedRange) pour laquelle les modifications doivent être extraites. Vous pouvez éventuellement utiliser maxItemCount dans ChangeFeedIteratorOptions pour définir le nombre maximal d’éléments reçus par page.

Remarque : si aucune valeur changeFeedStartFrom n’est spécifiée, le flux de modification est récupéré pour un conteneur entier à partir de Now().

Il existe quatre positions de départ pour le flux de modification :

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

Voici un exemple d’extraction du flux de modification pour une clé de partition

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
}

Étant donné que le flux de modification est effectivement une liste infinie d’éléments qui englobent toutes les écritures et mises à jour futures, la valeur de hasMoreResults est toujours true. Lorsque vous essayez de lire le flux de modification et qu’aucune nouvelle modification n’est disponible, vous recevez une réponse avec NotModified'état.

Des instructions d’utilisation plus détaillées et des exemples de flux de modification sont disponibles ici.

Gestion des erreurs

Le Kit de développement logiciel (SDK) génère différents types d’erreurs qui peuvent se produire pendant une opération.

  1. ErrorResponse est levée si la réponse d’une opération retourne un code d’erreur de >=400.
  2. TimeoutError est levée si Abort est appelé en interne en raison du délai d’expiration.
  3. AbortError est levée si un signal passé par l’utilisateur a provoqué l’abandon.
  4. RestError est levée en cas de défaillance de l’appel système sous-jacent en raison de problèmes réseau.
  5. Erreurs générées par les devDependencies. Par exemple. @azure/identity package peut lever CredentialUnavailableError.

Voici un exemple de gestion des erreurs de type ErrorResponse, TimeoutError, AbortErroret 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.
  }
}

Il est important de gérer correctement ces erreurs pour vous assurer que votre application peut récupérer correctement à partir de tout échec et continuer à fonctionner comme prévu. Vous trouverez plus d’informations sur certaines de ces erreurs et leurs solutions possibles ici.

Dépannage

Généralités

Lorsque vous interagissez avec les erreurs Cosmos DB retournées par le service correspondent aux mêmes codes d’état HTTP retournés pour les demandes d’API REST :

codes d’état HTTP pour Azure Cosmos DB

Conflits

Par exemple, si vous essayez de créer un élément à l’aide d’un id déjà utilisé dans votre base de données Cosmos DB, une erreur 409 est retournée, indiquant le conflit. Dans l’extrait de code suivant, l’erreur est gérée correctement en interceptant l’exception et en affichant des informations supplémentaires sur l’erreur.

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

Transpilation

Les kits de développement logiciel (SDK) Azure sont conçus pour prendre en charge la syntaxe JavaScript ES5 et versions LTS de Node.js. Si vous avez besoin de la prise en charge des runtimes JavaScript antérieurs tels qu’Internet Explorer ou Node 6, vous devez transpiler le code du SDK dans le cadre de votre processus de génération.

Gérer les erreurs temporaires avec les nouvelles tentatives

Lors de l’utilisation de Cosmos DB, vous pouvez rencontrer des défaillances temporaires causées par des limites de débit appliquées par le service, ou d’autres problèmes temporaires tels que les pannes réseau. Pour plus d’informations sur la gestion de ces types d’échecs, consultez modèle nouvelle tentative dans le guide des modèles de conception cloud et le modèle disjoncteur associé.

Exploitation forestière

L’activation de la journalisation peut vous aider à découvrir des informations utiles sur les échecs. Pour afficher un journal des requêtes et réponses HTTP, définissez la variable d’environnement AZURE_LOG_LEVEL sur info. Vous pouvez également activer la journalisation au moment de l’exécution en appelant setLogLevel dans le @azure/logger. Lors de l’utilisation de AZURE_LOG_LEVEL veillez à le définir avant l’initialisation de la bibliothèque de journalisation. Dans l’idéal, passez-le par le biais de la ligne de commande, si vous utilisez des bibliothèques comme dotenv assurez-vous que ces bibliothèques sont initialisées avant la journalisation de la bibliothèque.

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

Pour obtenir des instructions plus détaillées sur l’activation des journaux, vous pouvez consulter la documentationdu package @azure/enregistreur d’événements.

Diagnostic

La fonctionnalité Diagnostics Cosmos fournit des insights améliorés sur toutes vos opérations clientes. Un objet CosmosDiagnostics est ajouté à la réponse de toutes les opérations clientes. comme

  • Reponse de l’opération de recherche de point - item.read(), container.create(), database.delete()
  • Reponse de l’opération de requête -queryIterator.fetchAll(),
  • Opérations en bloc et batch -item.batch().
  • Objets de réponse d’erreur/exception.

Un objet CosmosDiagnostics est ajouté à la réponse de toutes les opérations clientes. Il existe 3 niveaux de diagnostic Cosmos, d’informations, de débogage et de débogage non sécurisés. Où seules les informations sont destinées aux systèmes de production et au débogage et non sécurisés sont destinées à être utilisées pendant le développement et le débogage, car elles consomment des ressources beaucoup plus élevées. Le niveau de diagnostic Cosmos peut être défini de 2 façons

  • Programmatiquement
  const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
  • Utilisation de variables d’environnement. (Le niveau de diagnostic défini par la variable d’environnement a une priorité plus élevée par rapport à sa définition via les options clientes.)
  export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"

Cosmos Diagnostic a trois membres

  • Type ClientSideRequestStatistics : contient des informations de diagnostic agrégées, notamment les recherches de métadonnées, les nouvelles tentatives, les points de terminaison contactés et les statistiques de demande et de réponse, telles que la taille et la durée de la charge utile. (est toujours collecté, peut être utilisé dans les systèmes de production.)

  • DiagnosticNode : structure de type arborescence qui capture des informations de diagnostic détaillées. Similaire à har enregistrement présent dans les navigateurs. Cette fonctionnalité est désactivée par défaut et est destinée au débogage d’environnements hors production uniquement. (collecté au niveau du diagnostic de débogage et non sécurisé)

  • ClientConfig : capture les informations essentielles relatives aux paramètres de configuration du client lors de l’initialisation du client. (collecté au niveau du diagnostic de débogage et non sécurisé)

Veillez à ne jamais définir le niveau de diagnostic sur debug-unsafe dans l’environnement de production, car ce niveau CosmosDiagnostics capture les charges utiles de demande et de réponse et si vous choisissez de le consigner (il est enregistré par défaut par @azure/logger au niveau verbose). Ces charges utiles peuvent être capturées dans vos récepteurs de journaux.

Consommation de diagnostics

  • Étant donné que diagnostics est ajouté à tous les objets Response. Vous pouvez programmer l’accès CosmosDiagnostic comme suit.
  // 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
  }
  • Vous pouvez également journaliser diagnostics à l’aide de @azure/logger, le diagnostic est toujours journalisé à l’aide de @azure/logger au niveau verbose. Par conséquent, si vous définissez le niveau diagnostic sur debug ou debug-unsafe et @azure/logger niveau sur verbose, diagnostics sera journalisé.

Étapes suivantes

Autres exemples de code

Plusieurs exemples sont disponibles dans le dépôt GitHub du KIT de développement logiciel (SDK). Ces exemples fournissent un exemple de code pour des scénarios supplémentaires couramment rencontrés lors de l’utilisation de Cosmos DB :

  • Opérations de base de données
  • Opérations de conteneur
  • Opérations d’élément
  • Configuration de l’indexation
  • Lecture d’un flux de modification de conteneur
  • Procédures stockées
  • Modification des paramètres de débit de base de données/conteneur
  • Opérations d’écriture multirégion

Limitations

Actuellement, les fonctionnalités ci-dessous ne sont pas prises en charge. Pour obtenir d’autres options, consultez la section Solutions de contournement ci-dessous.

Limitations du plan de données :

  • Requêtes avec COUNT à partir d’une sous-requête DISTINCT
  • Accès direct en mode TCP
  • Agréger des requêtes entre partitions, telles que le tri, le comptage et les distincts, ne prennent pas en charge les jetons de continuation. Requêtes streamables, telles que SELECT * FROM WHERE , prend en charge les jetons de continuation. Consultez la section « Solution de contournement » pour l’exécution de requêtes non streamables sans jeton de continuation.
  • Flux de modification : Processeur
  • Flux de modification : lire plusieurs valeurs de clé de partition
  • Prise en charge du modèle d’extraction de flux de modification pour les clés de partition hiérarchique partielles #27059
  • ORDER BY inter-partition pour les types mixtes
  • Limitations du plan de contrôle :

    • Obtenir les métriques CollectionSizeUsage, DatabaseUsage et DocumentUsage
    • Créer un index géospatial
    • Mettre à jour le débit de mise à l’échelle automatique

    Solutions de contournement

    Jeton de continuation pour les requêtes entre partitions

    Vous pouvez obtenir des requêtes entre partitions avec prise en charge des jetons de continuation à l’aide du modèle de voiture côté . Ce modèle peut également permettre aux applications d’être composées de composants et de technologies hétérogènes.

    Exécution d’une requête inter-partitions non stremable

    Pour exécuter des requêtes non streamables sans utiliser de jetons de continuation, vous pouvez créer un itérateur de requête avec la spécification et les options de requête requises. L’exemple de code suivant montre comment utiliser un itérateur de requête pour extraire tous les résultats sans avoir besoin d’un jeton de continuation :

    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
    }
    

    Cette approche peut également être utilisée pour les requêtes streamables.

    Opérations du plan de contrôle

    En règle générale, vous pouvez utiliser portail Azure, 'API REST du fournisseur de ressources Azure Cosmos DB, Azure CLI ou PowerShell pour les limitations non prises en charge du plan de contrôle.

    Documentation supplémentaire

    Pour plus d’informations sur le service Cosmos DB, consultez la documentation Azure Cosmos DB sur docs.microsoft.com.

    Contribuant

    Si vous souhaitez contribuer à cette bibliothèque, lisez le guide de contribution pour en savoir plus sur la génération et le test du code.

    Impressions