Compartir a través de


Biblioteca cliente de Azure Cosmos DB para JavaScript: versión 4.0.0

/TypeScript

último estadode compilación del distintivo de npm

Azure Cosmos DB es un servicio de base de datos multimodelo distribuido globalmente que admite bases de datos de documentos, pares clave-valor, basadas en columnas y gráficos. Este paquete está diseñado para que las aplicaciones javaScript/TypeScript interactúen con las bases de datos de LA API de SQL y los documentos JSON que contienen:

  • Creación de bases de datos de Cosmos DB y modificación de su configuración
  • Crear y modificar contenedores para almacenar colecciones de documentos JSON
  • Crear, leer, actualizar y eliminar los elementos (documentos JSON) en los contenedores
  • Consultar los documentos de la base de datos mediante la sintaxis similar a SQL

Vínculos principales:

Introducción

Requisitos previos

Suscripción de Azure y cuenta de SQL API de Cosmos DB

Debe tener una suscripción de Azure y una cuenta de Cosmos DB (SQL API) para usar este paquete.

Si necesita una cuenta de SQL API de Cosmos DB, puede usar Azure Cloud Shell para crear una con este comando de la CLI de Azure:

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

O puede crear una cuenta en Azure Portal

NodeJS

Este paquete se distribuye a través de npm, que viene preinstalado con NodeJS. Debe usar Node v10 o superior.

CORS

Debe configurar reglas de uso compartido de recursos entre orígenes (CORS) para la cuenta de Cosmos DB si necesita desarrollar para exploradores. Siga las instrucciones del documento vinculado para crear nuevas reglas de CORS para Cosmos DB.

Instalación de este paquete

npm install @azure/cosmos

Obtención de credenciales de la cuenta

Necesitará el punto de conexión y la clave de la cuenta de Cosmos DB. Puede encontrarlos en Azure Portal o usar el fragmento de código de la CLI de Azure siguiente. El fragmento de código tiene el formato para el shell de 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

Creación de una instancia de CosmosClient

La interacción con Cosmos DB comienza con una instancia de la clase 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);
});

Por motivos de simplicidad, hemos incluido key y endpoint directamente en el código, pero es probable que quiera cargarlos desde un archivo que no esté en el control de código fuente mediante un proyecto como dotenv o cargar desde variables de entorno

En entornos de producción, los secretos como las claves deben almacenarse en Azure Key Vault

Conceptos clave

Una vez que haya inicializado CosmosClient, puede interactuar con los tipos de recursos principales de Cosmos DB:

  • Base de datos: Una cuenta de Cosmos DB puede contener varias bases de datos. Al crear una base de datos, especifique la API que desea usar al interactuar con sus documentos: SQL, MongoDB, Gremlin, Cassandra, o Azure Table. Use el objeto Database para administrar sus contenedores.

  • Contenedor: Un contenedor es una colección de documentos JSON. Puede crear (insertar), leer, actualizar y eliminar elementos en un contenedor mediante métodos en el objeto Contenedor.

  • Elemento: Un elemento es un documento JSON almacenado en un contenedor. Cada elemento debe incluir una clave id con un valor que identifique de forma única el elemento dentro del contenedor. Si no se proporciona un id, el SDK generará uno automáticamente.

Para más información sobre estos recursos, consulte Uso de bases de datos, contenedores y elementos de Azure Cosmos.

Ejemplos

Las secciones siguientes proporcionan varios fragmentos de código que abarcan algunas de las tareas más comunes de Cosmos DB, entre las que se incluyen las siguientes:

Crear una base de datos

Después de autenticar CosmosClient, puede trabajar con cualquier recurso de la cuenta. El fragmento de código siguiente crea una base de datos de API NOSQL.

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

Crear un contenedor

En este ejemplo se crea un contenedor con la configuración predeterminada

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

Uso de claves de partición

En este ejemplo se muestran varios tipos de claves de partición admitidas.

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 clave de partición consta de un único valor, se podría proporcionar como un valor literal o como una matriz.

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

Si la clave de partición consta de más de un valor, se debe proporcionar como una 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();

Inserción de elementos

Para insertar elementos en un contenedor, pase un objeto que contenga los datos a Items.upsert. El servicio Azure Cosmos DB requiere que cada elemento tenga una id clave. Si no se proporciona, el SDK generará una id automáticamente.

En este ejemplo se insertan varios elementos en el contenedor

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

Lectura de un elemento

Para leer un solo elemento de un contenedor, use Item.read. Se trata de una operación menos costosa que el uso de SQL para consultar mediante id.

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

CRUD en contenedor con clave de partición jerárquica

Creación de un contenedor con clave de partición jerá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);

Insertar un elemento con la clave de partición jerárquica definida como : ["/name", "/address/zip"]

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

Para leer un solo elemento de un contenedor con clave de partición jerárquica definida como : ["/name", "/address/zip"],

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

Consulta de un elemento con clave de partición jerárquica con clave de partición jerá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} `);
}

Eliminación de un elemento

Para eliminar elementos de un contenedor, use Item.delete.

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

Consulta de la base de datos

Una base de datos de SQL API de Cosmos DB admite la consulta de los elementos de un contenedor con Items.query mediante una sintaxis similar 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 `);
}

Para realizar consultas con parámetros, pase un objeto que contenga los parámetros y sus valores 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 `);
}

Para más información sobre cómo consultar bases de datos de Cosmos DB mediante SQL API, consulte Consulta de datos de Azure Cosmos DB con consultas SQL.

Modelo de extracción de fuente de cambios

La fuente de cambios se puede capturar para una clave de partición, un intervalo de fuentes o un contenedor completo.

Para procesar la fuente de cambios, cree una instancia de ChangeFeedPullModelIterator. Al crear ChangeFeedPullModelIteratorinicialmente , debe especificar un valor necesario changeFeedStartFrom dentro del ChangeFeedIteratorOptions que consta de la posición inicial para leer los cambios y el recurso (una clave de partición o un FeedRange) para los que se van a capturar los cambios. Opcionalmente, puede usar maxItemCount en ChangeFeedIteratorOptions para establecer el número máximo de elementos recibidos por página.

Nota: Si no se especifica ningún changeFeedStartFrom valor, se capturará changefeed para un contenedor completo de Now().

Hay cuatro posiciones iniciales para la fuente de cambios:

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

Este es un ejemplo de captura de fuente de cambios para una clave de partición.

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
}

Dado que la fuente de cambios es realmente una lista infinita de elementos que abarcan todas las escrituras y actualizaciones futuras, el valor de hasMoreResults siempre es true. Al intentar leer la fuente de cambios y no haber nuevos cambios disponibles, recibirá una respuesta con el estado NotModified.

Aquí encontrará instrucciones de uso más detalladas y ejemplos de fuente de cambios.

Tratamiento de errores

El SDK genera varios tipos de errores que pueden producirse durante una operación.

  1. ErrorResponse se produce si la respuesta de una operación devuelve un código de error de >=400.
  2. TimeoutError se produce si se llama a Abort internamente debido al tiempo de espera.
  3. AbortError se produce si algún usuario pasó la señal causó la anulación.
  4. RestError se produce en caso de error de la llamada del sistema subyacente debido a problemas de red.
  5. Errores generados por cualquier devDependencies. Por ejemplo, @azure/identity el paquete podría producir CredentialUnavailableError.

A continuación se muestra un ejemplo para controlar errores de tipo ErrorResponse, TimeoutError, AbortErrory 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.
  }
}

Es importante controlar correctamente estos errores para asegurarse de que la aplicación pueda recuperarse correctamente de los errores y seguir funcionando según lo previsto. Puede encontrar más detalles sobre algunos de estos errores y sus posibles soluciones aquí.

Solución de problemas

General

Al interactuar con Cosmos DB, los errores devueltos por el servicio se corresponden con los mismos códigos de estado HTTP devueltos para las solicitudes de API de REST:

Códigos de estado HTTP para Azure Cosmos DB

Conflictos

Por ejemplo, si intenta crear un elemento mediante un id que ya está en uso en la base de datos de Cosmos DB, se devuelve un error 409, lo que indica el conflicto. En el siguiente fragmento, el error se controla correctamente al detectar la excepción y mostrar información adicional sobre el error.

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

Transpilación

Los SDK de Azure están diseñados para admitir la sintaxis de JavaScript ES5 y las versiones LTS de Node.js. Si necesita compatibilidad con entornos de ejecución de JavaScript anteriores, como Internet Explorer o Node 6, deberá transpilar el código del SDK como parte del proceso de compilación.

Control de errores transitorios con reintentos

Al trabajar con Cosmos DB, puede encontrar errores transitorios producidos por límites de frecuencia aplicados por el servicio u otros problemas transitorios, como interrupciones de red. Para información sobre cómo controlar estos tipos de errores, consulte la sección sobre el patrón Retry en la guía de patrones de diseño en la nube y el patrón Circuit Breaker relacionado.

Registro

La habilitación del registro puede ayudar a descubrir información útil sobre los errores. Para ver un registro de solicitudes y respuestas HTTP, establezca la variable de entorno AZURE_LOG_LEVEL en info. Como alternativa, el registro se puede habilitar en tiempo de ejecución llamando a setLogLevel en .@azure/logger Al usar AZURE_LOG_LEVEL asegúrese de establecerlo antes de inicializar la biblioteca de registro. Lo ideal es pasarla a través de la línea de comandos, si usa bibliotecas como dotenv asegurarse de que estas bibliotecas se inicializan antes de registrarla.

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

Para obtener instrucciones más detalladas sobre cómo habilitar los registros, consulte los documentos del paquete @azure/logger.

Diagnóstico

La característica Diagnósticos de Cosmos proporciona información mejorada sobre todas las operaciones de cliente. Se agrega un objeto CosmosDiagnostics a la respuesta de todas las operaciones de cliente. Por ejemplo,

  • Repositorio de la operación de búsqueda de puntos: item.read(), container.create(), database.delete()
  • Repositorio de la operación de consulta -queryIterator.fetchAll(),
  • Operaciones masivas y por lotes :item.batch().
  • Objetos de respuesta error/excepción.

Se agrega un objeto CosmosDiagnostics a la respuesta de todas las operaciones de cliente. Hay 3 niveles de diagnóstico de Cosmos, información, depuración y debug-unsafe. Donde solo la información está pensada para sistemas de producción y depuración y debug-unsafe están pensadas para usarse durante el desarrollo y la depuración, ya que consumen recursos significativamente más altos. El nivel de diagnóstico de Cosmos se puede establecer de dos maneras

  • Mediante programación
  const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
  • Uso de variables de entorno. (El nivel de diagnóstico establecido por variable de entorno tiene mayor prioridad sobre cómo establecerlo a través de las opciones de cliente).
  export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"

Cosmos Diagnostic tiene tres miembros

  • Tipo ClientSideRequestStatistics: contiene detalles de diagnóstico agregados, incluidas búsquedas de metadatos, reintentos, puntos de conexión contactados y estadísticas de solicitud y respuesta, como el tamaño y la duración de la carga. (siempre se recopila, se puede usar en sistemas de producción).

  • DiagnosticNode: es una estructura similar a un árbol que captura información detallada de diagnóstico. Similar a la har grabación presente en exploradores. Esta característica está deshabilitada de forma predeterminada y está pensada solo para depurar entornos que no son de producción. (recopilados en el nivel de diagnóstico de depuración y debug-unsafe)

  • ClientConfig: captura información esencial relacionada con la configuración del cliente durante la inicialización del cliente. (recopilados en el nivel de diagnóstico de depuración y debug-unsafe)

Asegúrese de no establecer nunca el nivel debug-unsafe de diagnóstico en en el entorno de producción, ya que este nivel CosmosDiagnostics captura las cargas de solicitud y respuesta y si decide registrarlo (se registra @azure/logger de forma predeterminada en el verbose nivel). Estas cargas pueden capturarse en los receptores de registro.

Consumo de diagnósticos

  • Dado diagnostics que se agrega a todos los objetos Response. Puede acceder CosmosDiagnostic mediante programación como se indica a continuación.
  // 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
  }
  • También puede registrar diagnostics con @azure/logger, el diagnóstico siempre se registra mediante @azure/logger en el verbose nivel . Por lo tanto, si establece el nivel debug de diagnóstico en o debug-unsafe y @azure/loggerverboseen , diagnostics se registrará.

Pasos siguientes

Más código de ejemplo

Hay varios ejemplos en el repositorio de GitHub del SDK. Estos ejemplos proporcionan código de ejemplo de escenarios adicionales que suelen aparecer al trabajar con Cosmos DB:

  • Operaciones de base de datos
  • Operaciones de contenedor
  • Operaciones de elemento
  • Configuración de la indexación
  • Lectura de una fuente de cambios de contenedor
  • Procedimientos almacenados
  • Cambio de la configuración de rendimiento de base de datos o contenedor
  • Operaciones de escritura en varias regiones

Limitaciones

Actualmente no se admiten las características siguientes. Para ver las opciones alternativas, consulte la sección Soluciones alternativas a continuación.

Limitaciones del plano de datos:

  • Consultas con COUNT desde una subconsulta DISTINCT
  • Acceso directo al modo TCP
  • Las consultas agregadas entre particiones, como la ordenación, el recuento y la diferenciación, no admiten tokens de continuación. Consultas que se pueden transmitir, como SELECT * FROM WHERE , admite tokens de continuación. Consulte la sección "Solución alternativa" para ejecutar consultas que no se pueden transmitir sin un token de continuación.
  • Fuente de cambios: procesador
  • Fuente de cambios: leer varios valores de clave de particiones
  • Modelo de extracción de fuente de cambios todas las versiones y modo de eliminación n.º 27058
  • Compatibilidad del modelo de extracción de fuente de cambios para claves de partición jerárquicas parciales #27059
  • ORDER BY entre particiones para tipos mixtos
  • Limitaciones del plano de control:

    • Obtener métricas CollectionSizeUsage, DatabaseUsage y DocumentUsage
    • Creación de un índice geoespacial
    • Actualización del rendimiento de escalabilidad automática

    Soluciones alternativas

    Token de continuación para consultas entre particiones

    Puede lograr consultas entre particiones con compatibilidad con tokens de continuación mediante el patrón side car. Este patrón también puede habilitar las aplicaciones compuestas de tecnologías y componentes heterogéneos.

    Ejecución de una consulta entre particiones no estremable

    Para ejecutar consultas que no se pueden transmitir sin el uso de tokens de continuación, puede crear un iterador de consulta con las opciones y la especificación de consulta necesarias. En el código de ejemplo siguiente se muestra cómo usar un iterador de consulta para capturar todos los resultados sin necesidad de un token de continuación:

    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
    }
    

    Este enfoque también se puede usar para las consultas que se pueden transmitir.

    Operaciones del plano de control

    Normalmente, puede usar Azure Portal, la API REST del proveedor de recursos de Azure Cosmos DB, la CLI de Azure o PowerShell para las limitaciones no admitidas del plano de control.

    Documentación adicional

    Para obtener documentación ampliada sobre el servicio Cosmos DB, consulte la documentación de Azure Cosmos DB en docs.microsoft.com.

    Contribuciones

    Si desea contribuir a esta biblioteca, lea la guía de contribución para obtener más información sobre cómo compilar y probar el código.

    Impresiones