Compartir a través de


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

/Mecanografiado

notificación más reciente de npm estado de compilación

Azure Cosmos DB es un servicio de base de datos multimodelo distribuido globalmente que admite bases de datos document, key-value, wide-column y graph. Este paquete está diseñado para que las aplicaciones javaScript/TypeScript interactúen con bases de datos de SQL API y los documentos JSON que contienen:

  • Creación de bases de datos de Cosmos DB y modificación de su configuración
  • Creación y modificación de contenedores para almacenar colecciones de documentos JSON
  • Creación, lectura, actualización y eliminación de los elementos (documentos JSON) en los contenedores
  • Consulta de los documentos de la base de datos mediante la sintaxis similar a SQL

Vínculos clave:

  • paquete (npm)
  • documentación de referencia de api de
  • documentación del producto de

Empezar

Prerrequisitos

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

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

Si necesita una cuenta de SQL API de Cosmos DB, puede usar la de 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 bien, puede crear una cuenta en el de Azure Portal de

NodeJS

Este paquete se distribuye a través de npm que viene preinstalado con NodeJS mediante una versión LTS.

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 cuenta

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

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, hemos incluido el 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 uncosmosClient de , puede interactuar con los tipos de recursos principales de Cosmos DB:

  • Database: 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.

  • container: 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 Container .

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

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

Ejemplos

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

Creación de una base de datos

Después de autenticar elde CosmosClient de , 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);

Creación de 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 valor único, podría proporcionarse como un valor literal o 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();

Insertar 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 clave id. Si no proporciona una, el SDK generará automáticamente un id.

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

Leer 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 realizar consultas 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 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} `);
}

Eliminar 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 la 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 obtener más información sobre cómo consultar bases de datos de Cosmos DB mediante la API de SQL, 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 fuente o un contenedor completo.

Para procesar la fuente de cambios, cree una instancia de ChangeFeedPullModelIterator. Al crear inicialmente ChangeFeedPullModelIterator, debe especificar un valor de changeFeedStartFrom necesario dentro de la 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 valor changeFeedStartFrom, 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 efectivamente una lista infinita de elementos que abarca todas las escrituras y actualizaciones futuras, el valor de hasMoreResults siempre es true. Al intentar leer la fuente de cambios y no hay nuevos cambios disponibles, recibirá una respuesta con NotModified estado.

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

Control 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 provocó la anulación.
  4. RestError se produce en caso de error de llamada del sistema subyacente debido a problemas de red.
  5. Errores generados por cualquier devDependencies. Por ejemplo, por ejemplo, @azure/identity paquete podría iniciar 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

Cuando interactúa con los errores de Cosmos DB devueltos por el servicio, corresponden a los mismos códigos de estado HTTP devueltos para las solicitudes de la API REST:

códigos de estado HTTP para de 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 de 409, lo que indica el conflicto. En el fragmento de código siguiente, el error se controla correctamente detectando la excepción y mostrando 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 versiones LTS de Node.js. Si necesita compatibilidad con entornos de ejecución de JavaScript anteriores, como Internet Explorer o Node 6, deberá transpile el código del SDK como parte del proceso de compilación.

Control de errores transitorios con reintentos

Al trabajar con Cosmos DB, es posible que encuentre errores transitorios causados por límites de velocidad aplicados por el servicio u otros problemas transitorios, como interrupciones de red. Para obtener información sobre cómo controlar estos tipos de errores, consulte patrón de reintento en la guía Patrones de diseño en la nube y el patrón Circuit Breaker relacionado.

Registro

Habilitar el registro puede ayudar a descubrir información útil sobre 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 el @azure/logger. Al usar AZURE_LOG_LEVEL asegúrese de establecerla 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 asegúrese de que estas bibliotecas se inicializan antes de registrar la biblioteca.

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

Para obtener instrucciones más detalladas sobre cómo habilitar los registros, puede consultar los documentos del paquete de @azure/registrador.

Diagnósticos

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. como

  • Repositorio de operaciones de búsqueda de puntos: item.read(), container.create(), database.delete()
  • Repositorio de operaciones 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 depuración-unsafe. Donde solo la información está pensada para sistemas de producción y depuración y depuración-unsafe están diseñadas para usarse durante el desarrollo y la depuración, ya que consumen recursos significativamente mayores. 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 la 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

  • ClientSideRequestStatistics Type: contiene detalles de diagnóstico agregados, incluidas las búsquedas de metadatos, los reintentos, los puntos de conexión contactados y las estadísticas de solicitud y respuesta, como el tamaño de carga y la duración. (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 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. (recopilado en el nivel de diagnóstico, depuración y depuración no segura)

  • ClientConfig: captura información esencial relacionada con la configuración del cliente durante la inicialización del cliente. (recopilado en el nivel de diagnóstico, depuración y depuración no segura)

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

Consumo de diagnósticos

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

Pasos siguientes

Más código de ejemplo

hay varios ejemplos disponibles en el repositorio de GitHub del SDK. Estos ejemplos proporcionan código de ejemplo para escenarios adicionales que se encuentran habitualmente al trabajar con Cosmos DB:

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

Limitaciones

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

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 los distintos, 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
  • 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 patrón de automóvil lateral. Este patrón también puede permitir que las aplicaciones se componen de componentes y tecnologías 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 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
    }
    

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

    Operaciones del plano de control

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

    Documentación adicional

    Para más información sobre el servicio Cosmos DB, consulte la documentación de Azure Cosmos DB en docs.microsoft.com.

    Contribuyendo

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

    impresiones