Поделиться через


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

/Машинописный текст

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

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

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

Ключевые ссылки:

  • пакет (npm)
  • Справочная документация по API
  • документации по продукту

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

Необходимые условия

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

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

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

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

Или вы можете создать учетную запись на портале Azure

NodeJS

Этот пакет распространяется через npm, который предварительно установлен с NodeJS с помощью версии LTS.

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. Используйте объект базы данных для управления контейнерами.

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

  • элемент: элемент является документом 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();

Запрос базы данных

База данных API SQL Cosmos DB поддерживает запросы элементов в контейнере с 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 см. в статье Запрос данных Azure Cosmos DB с помощью запросов SQL.

Модель извлечения канала изменений

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

Чтобы обработать канал изменений, создайте экземпляр 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. Для Eg. @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");
  }
}

Транспилирование

Пакеты SDK Azure предназначены для поддержки синтаксиса 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/loger.

Диагностика

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

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

Объект CosmosDiagnostics добавляется в ответ на все клиентские операции. Существует 3 уровня диагностики Cosmos, сведения, отладка и отладка. Где только сведения предназначены для производственных систем и отладки и небезопасной отладки, предназначены для использования во время разработки и отладки, так как они используют значительно более высокие ресурсы. Уровень диагностики Cosmos можно задать 2 способами

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

В диагностике Cosmos есть три члена

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

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

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

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

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

  • Так как diagnostics добавляется ко всем объектам Ответа. Вы можете программно получить доступ 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 пакета SDK. В этих примерах приведен пример кода для дополнительных сценариев, часто встречающихся при работе с Cosmos DB:

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

Ограничения

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

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

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

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

    Обходные пути

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

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

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

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

    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
    }
    

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

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

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

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

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

    Способствует

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

    впечатлений