Клиентская библиотека Azure Cosmos DB для JavaScript версии 4.0.0

/Typescript

Последний индикатор состояниясборки npm

Azure Cosmos DB — это глобально распределенная многомодельная служба баз данных, которая поддерживает базы данных документов, пар "ключ-значение" и графов, а также базы данных с широкими столбцами. Этот пакет предназначен для взаимодействия приложений JavaScript и TypeScript с базами данных API SQL и содержащимися в них документами JSON:

  • Создание баз данных Cosmos DB и изменение их параметров
  • Создание и изменение контейнеров для хранения коллекций документов JSON
  • Создание, чтение, обновление и удаление элементов (документов JSON) в контейнерах
  • Запрос документов в базе данных с помощью синтаксиса, аналогичного SQL

Основные ссылки:

Начало работы

Предварительные требования

Подписка Azure и учетная запись API SQL для Cosmos DB

Для использования этого пакета необходимо иметь подписку Azure и учетную запись Cosmos DB (API SQL).

Если вам нужна учетная запись API SQL для Cosmos DB, ее можно создать в службе Azure Cloud Shell с помощью следующей команды Azure CLI:

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

Учетную запись также можно создать на портале Azure.

Node.js

Этот пакет распространяется через диспетчер npm, который предустанавливается вместе с NodeJS. Следует использовать node.js 10 или более поздней версии.

CORS

Чтобы разрабатывать решения для браузеров, необходимо настроить правила общего доступа к ресурсам независимо от источника (CORS) для учетной записи Cosmos DB. Следуйте инструкциям в связанном документе, чтобы создать новые правила CORS для Cosmos DB.

Установка пакета

npm install @azure/cosmos

Получение учетных данных учетной записи

Вам потребуется конечная точка и ключ учетной записи для Cosmos DB. Их можно узнать на портале Azure или выполнив фрагмент кода Azure CLI ниже. Фрагмент кода отформатирован для оболочки 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

Создание экземпляра CosmosClient

Взаимодействие с Cosmos DB осуществляется через экземпляр класса 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);
});

Для простоты мы включили параметры key и endpoint непосредственно в код, но вы, вероятно, возьмете их из файла, не включенного в систему управления версиями, с помощью проекта, например dotenv, или загрузите из переменных среды.

В рабочих средах такие секреты, как ключи, должны храниться в Azure Key Vault

Основные понятия

После инициализации CosmosClient можно работать с ресурсами основных типов в Cosmos DB:

  • База данных: Учетная запись Cosmos DB может предоставлять доступ к нескольким базам данных. При создании базы данных задается API, который будет использоваться для работы с документами в ней: SQL, MongoDB, Gremlin, Cassandra или Azure Table. Используйте объект Database для управления контейнерами.

  • Контейнер: Контейнер — это набор документов JSON. Создание (вставка), чтение, обновление и удаление элементов в контейнере выполняется с помощью методов объекта Container.

  • Элемент. Элемент — это документ JSON, хранящийся в контейнере. Каждый элемент должен содержать ключ id со значением, которое уникальным образом определяет элемент в контейнере. Если не указать id, пакет SDK создаст его автоматически.

Дополнительные сведения об этих ресурсах см. в статье Работа с базами данных, контейнерами и элементами Azure Cosmos.

Примеры

В следующих разделах приведено несколько фрагментов кода для наиболее распространенных задач в Cosmos DB.

Создание базы данных

После проверки подлинности CosmosClient можно работать с любым ресурсом в учетной записи. Приведенный ниже фрагмент кода создает базу данных API NOSQL.

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

Создание контейнера

В этом примере создается контейнер с параметрами по умолчанию

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

Использование ключей секций

В этом примере показаны различные типы поддерживаемых ключей секций.

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

Если ключ секции состоит из одного значения, его можно указать либо в виде литерального значения, либо в виде массива.

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

Если ключ секции состоит из нескольких значений, он должен быть указан в виде массива.

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

Вставка элементов

Чтобы вставить элементы в контейнер, передайте объект, содержащий данные, в Items.upsert. Службе Azure Cosmos DB требуется, чтобы у каждого элемента был id ключ. Если его не указать, пакет SDK создаст id автоматически.

В этом примере в контейнер вставляется несколько элементов.

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

Чтение элемента

Чтобы прочитать один элемент из контейнера, используйте метод Item.read. Это менее ресурсоемкая операция, чем использование SQL для запросаid.

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

CRUD в контейнере с иерархическим ключом секции

Создание контейнера с иерархическим ключом секции

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

Вставка элемента с иерархическим ключом секции, определенным как : ["/name", "/address/zip"]

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

Чтение одного элемента из контейнера с иерархическим ключом секции, определенным как : ["/name", "/address/zip"],

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

Запрос элемента с иерархическим ключом секции с иерархическим ключом секции, определенным как : ["/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} `);
}

Удаление элемента

Чтобы удалить элементы из контейнера, используйте метод Item.delete.

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

Выполнение запросов к базе данных

База данных Cosmos DB с поддержкой API SQL позволяет выполнять запросы элементов в контейнере с помощью метода Items.query, синтаксис которого аналогичен 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 `);
}

Выполняйте параметризованные запросы, передавая объект с параметрами и их значениями в метод 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 `);
}

Дополнительные сведения о запросах к базам данных Cosmos DB с помощью API SQL см. в статье SQL-запросы к базе данных Azure Cosmos DB".

Модель по запросу канала изменений

Канал изменений можно получить для ключа секции, диапазона канала или всего контейнера.

Чтобы обработать канал изменений, создайте экземпляр ChangeFeedPullModelIterator. При первоначальном создании ChangeFeedPullModelIteratorнеобходимо указать обязательное changeFeedStartFrom значение внутри ChangeFeedIteratorOptions , которое состоит из начальной позиции для чтения изменений и ресурса (ключа секции или FeedRange), для которого требуется получить изменения. При необходимости можно использовать maxItemCount в ChangeFeedIteratorOptions , чтобы задать максимальное количество элементов, полученных на страницу.

Примечание. Если значение не changeFeedStartFrom указано, функция changefeed будет получена для всего контейнера из Now().

Существует четыре начальные позиции для канала изменений:

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

Ниже приведен пример получения канала изменений для ключа секции.

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
}

Так как канал изменений фактически является бесконечным списком элементов, охватывающим все будущие операции записи и обновления, значение hasMoreResults всегда trueравно . При попытке прочитать веб-канал изменений, когда новые изменения отсутствуют, вы получаете ответ с NotModified состоянием.

Более подробные рекомендации по использованию и примеры веб-канала изменений можно найти здесь.

Обработка ошибок

Пакет SDK создает различные типы ошибок, которые могут возникнуть во время операции.

  1. ErrorResponse возникает, если ответ операции возвращает код >ошибки =400.
  2. TimeoutError вызывается, если прерывание вызывается внутренним образом из-за истечения времени ожидания.
  3. AbortError возникает, если какой-либо переданный пользователем сигнал вызвал прерывание.
  4. RestError возникает в случае сбоя базового системного вызова из-за проблем с сетью.
  5. Ошибки, созданные любыми devDependencies. Например, @azure/identity Пакет может вызвать исключение CredentialUnavailableError.

Ниже приведен пример обработки ошибок типа ErrorResponse, TimeoutError, AbortErrorи 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.
  }
}

Важно правильно обрабатывать эти ошибки, чтобы обеспечить корректное восстановление приложения после сбоев и продолжение работы должным образом. Дополнительные сведения о некоторых из этих ошибок и их возможных решениях можно найти здесь.

Устранение неполадок

Общие сведения

При работе с Cosmos DB ошибки, возвращаемые службой, соответствуют тем же кодам состояния HTTP, которые возвращаются для запросов REST API.

Коды состояния HTTP для Azure Cosmos DB

Конфликты

Например, при попытке создать элемент с помощью идентификатора id, который уже используется в базе данных Cosmos DB, возвращается ошибка 409, указывающая на наличие конфликта. В следующем фрагменте кода ошибка корректно обрабатывается путем перехвата исключения и отображения дополнительной информации об этой ошибке.

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

Компиляция в код на другом языке

Пакеты Azure SDK поддерживают синтаксис JavaScript ES5 и версии LTS для Node.js. Если вам нужна поддержка более ранних сред выполнения JavaScript, таких как Internet Explorer или Node 6, потребуется соответствующим образом скомпилировать код пакета SDK в процессе сборки.

Обработка временных ошибок с помощью повторных вызовов

При работе с Cosmos DB могут возникать временные сбои, вызванные ограничениями скорости, применяемыми службой, или другие периодические проблемы, такие как отказ сети. Для получения дополнительной информации об обработке этих типов сбоев ознакомьтесь со статьей Шаблон повторов в руководстве по конструктивным шаблонам облачных решений и соответствующим шаблоном автоматического выключения.

Ведение журнала

Включение ведения журнала может помочь выявить полезные сведения о сбоях. Чтобы просмотреть журнал HTTP-запросов и ответов, задайте для переменной среды AZURE_LOG_LEVEL значение info. Кроме того, ведение журнала можно включить во время выполнения, вызвав setLogLevel в @azure/logger. При использовании AZURE_LOG_LEVEL обязательно установите его перед инициализацией библиотеки ведения журнала. В идеале перед ведением журнала необходимо передать его через командную строку, если вы используете такие библиотеки, например dotenv , убедитесь, что такие библиотеки инициализированы.

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

Более подробные инструкции по включению журналов см. в документации по пакету @azure и средства ведения журнала.

Диагностика

Функция диагностики Cosmos предоставляет расширенные аналитические сведения обо всех операциях клиента. Объект CosmosDiagnostics добавляется в ответ на все операции клиента. Например

  • Повторная операция поиска точки — item.read(), container.create(), database.delete()
  • Reponse операции запроса -queryIterator.fetchAll(),
  • Массовые и пакетные операции .item.batch().
  • Объекты ответа об ошибках и исключениях.

Объект CosmosDiagnostics добавляется в ответ на все операции клиента. Существует 3 уровня диагностики Cosmos: info, debug и debug-unsafe. Если только информация предназначена для рабочих систем, и отладка и небезопасные для отладки предназначены для использования во время разработки и отладки, так как они потребляют значительно больше ресурсов. Уровень диагностики Cosmos можно задать 2 способами

  • Программный способ
  const client = new CosmosClient({ endpoint, key, diagnosticLevel: CosmosDbDiagnosticLevel.debug });
  • Использование переменных среды. (Уровень диагностики, заданный переменной среды, имеет более высокий приоритет, чем его установка с помощью параметров клиента.)
  export AZURE_COSMOSDB_DIAGNOSTICS_LEVEL="debug"

Диагностика Cosmos состоит из трех элементов

  • Тип ClientSideRequestStatistics: содержит статистические сведения о диагностике, в том числе поиск метаданных, повторные попытки, конечные точки, с которых были контактированы конечные точки, а также статистику запросов и ответов, таких как размер и длительность полезных данных. (всегда собирается, может использоваться в рабочих системах.)

  • DiagnosticNode: древовидная структура, которая собирает подробные диагностические сведения. Аналогично записи, har присутствующей в браузерах. Эта функция отключена по умолчанию и предназначена только для отладки нерабочих сред. (собирается на уровне диагностики debug и debug-unsafe)

  • ClientConfig: записывает важные сведения, связанные с параметрами конфигурации клиента во время инициализации клиента. (собирается на уровне диагностики debug и debug-unsafe)

Не устанавливайте уровень debug-unsafe диагностики в рабочей среде, так как этот уровень CosmosDiagnostics фиксирует полезные данные запросов и ответов и, если вы решили заносить их в журнал (по умолчанию регистрируется @azure/logger на verbose уровне). Эти полезные данные могут быть записаны в приемниках журналов.

Использование диагностики

  • Поскольку diagnostics добавляется ко всем объектам Response. Вы можете получить программный доступ CosmosDiagnostic , как показано ниже.
  // 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
  }
  • Вы также можете регистрироваться diagnostics с помощью @azure/logger, диагностика всегда регистрируется с помощью @azure/logger на verbose уровне. Таким образом, если для параметра Уровень диагностики задано debug значение или debug-unsafe , а @azure/logger для verboseуровня задано значение , diagnostics будет записано в журнал.

Дальнейшие действия

Больше примеров кода

Несколько примеров доступны в репозитории GitHub. В них содержится код для других ситуаций, которые часто возникают при работе с Cosmos DB:

  • Операции с базой данных
  • Операции с контейнерами
  • Операции над элементами
  • Настройка индексирования
  • Чтение канала изменений контейнера
  • Хранимые процедуры
  • Изменение параметров пропускной способности базы данных и контейнера
  • Операции записи в нескольких регионах

Ограничения

В настоящее время приведенные ниже функции не поддерживаются. Варианты альтернативных вариантов проверка в разделе Обходные пути ниже.

Ограничения плоскости данных:

  • Запросы со значением COUNT из вложенного запроса DISTINCT
  • Прямой доступ в режиме TCP
  • Агрегированные межсекционные запросы, такие как сортировка, подсчет и разделение, не поддерживают маркеры продолжения. Потоковые запросы, такие как SELECT * FROM WHERE , поддерживают маркеры продолжения. Сведения о выполнении непотоковых запросов без маркера продолжения см. в разделе "Обходное решение".
  • Канал изменений: обработчик
  • Канал изменений: чтение значений ключей нескольких секций
  • Модель по запросу канала изменений для всех версий и режим удаления #27058
  • Поддержка модели извлечения канала изменений для частичных иерархических ключей секций #27059
  • Cross-partition ORDER BY для смешанных типов
  • Ограничения уровня управления:

    • Получение метрик CollectionSizeUsage, DatabaseUsage и DocumentUsage
    • Создание геопространственного индекса
    • Обновление пропускной способности автомасштабирования

    Методы обхода проблемы

    Маркер продолжения для запросов между секциями

    Вы можете реализовать межсекционные запросы с поддержкой маркеров продолжения с помощью шаблона side car. Этот шаблон также может включать возможность создания приложений, состоящих из разнородных компонентов и технологий.

    Выполнение запроса между секциями без перестроения

    Чтобы выполнять непотоковые запросы без использования маркеров продолжения, можно создать итератор запроса с требуемой спецификацией и параметрами запроса. В следующем примере кода показано, как использовать итератор запроса для получения всех результатов без использования маркера продолжения.

    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
    }
    

    Этот подход также можно использовать для потоковых запросов.

    Операции уровня управления

    Как правило, для неподдерживаемых ограничений уровня управления можно использовать портал Azure, REST API поставщика ресурсов Azure Cosmos DB, Azure CLI или PowerShell .

    Дополнительная документация

    Более подробную документацию по службе Cosmos DB см. в документации по Azure Cosmos DB на портале docs.microsoft.com.

    Участие

    Если вы хотите вносить изменения в эту библиотеку, ознакомьтесь с руководством по внесению изменений, в котором содержатся сведения о создании и тестировании кода.

    Просмотры