【问题标题】:How to check if a container exists in cosmos DB using the node sdk?如何使用节点 sdk 检查容器是否存在于 cosmos DB 中?
【发布时间】:2021-10-10 06:01:34
【问题描述】:

我想检查一个容器是否存在,如果不存在,初始化它。我希望得到类似以下的内容:

const { endpoint, key, databaseId } = config;
const containerName = "container1"
const client = new CosmosClient({ endpoint ,key});
const containerDefinition = getContainerDefinition(containerName);
const db = await createDatabase(client, databaseId);
if (!db.containers.contains(containerName)
{
 // Do something
}

我不使用“createIfNotExists”的原因是我需要进行第二次调用以检查返回的容器是否填充了项目。我正在创建的容器将保存设置数据,一旦最初创建容器,这些数据将是静态的。此设置检查将根据请求进行,因此我希望尽可能减少数据库调用和操作。

我尝试做类似的事情:

try
{
 db.container(containerName).read();
}
catch(err)
{
  if(err.message.contains("Resource Not Found"))
  {
    // do something
  }
}

但这似乎不是正确的做法。

任何帮助将不胜感激!

【问题讨论】:

  • 为什么不在应用启动时执行 createIfNotExists?
  • 这是通过 azure 函数部署的。在有人调用该特定函数之前,容器不会被初始化。

标签: javascript node.js typescript azure-cosmosdb


【解决方案1】:

我不太清楚您为什么需要这样做,因为通常您只需要在应用程序实例的生命周期内执行一次此类操作。但我不建议这样做。

当您查询 Cosmos 以测试数据库、容器等是否存在时,这会命中帐户的主分区。主分区有点像一个小型 Cosmos 数据库,其中包含您所有的帐户元数据。

这个主分区被分配了少量管理元数据操作的 RU/s。因此,如果您的应用旨在针对每个请求进行这些类型的调用,那么您的应用很可能会受到速率限制。

如果您可以通过某种方式进行设计,使其不必查询容器的存在,那么我会改为这样做。

【讨论】:

  • @MarkBrown...Cosmos DB 团队对此有何建议?这是否应该作为帐户创建过程的一部分来完成(通过用于资源创建的 ARM 模板+用于初始种子数据的 SDK)?
  • @MarkBrown,我目前正在将 azure 函数与 cosmosDB 一起使用,并且每个函数都对应一个容器。当一个函数被调用时,它会在容器上调用 createIfNotExists 来创建它们(如果它们不在数据库中)。是否也应该不使用它,因为 createIfNotExistst 也会查询主分区?
  • @GauravMantri,我们的建议是,当应用程序启动时,它会创建对任何数据库/容器对象的静态引用,并在应用程序的生命周期内保持它们的活动状态。
  • @avenmia,是的 CreateIfNotExist 命中主分区。可以调用函数的启动。但我不会对每个请求都这样做。您应该为 CosmosClient 和您需要的任何 Container 引用创建静态引用,并在应用程序的生命周期内保持它们的活动状态。
【解决方案2】:

有趣的问题。所以我认为你的选择很少

  1. 只需调用const { container } = await database.containers.createIfNotExists({ id: "Container" });,它可能会快几毫秒,因为我通过代码看起来它总是会尝试从 cosmos 中读取 :( 如果你还想检查容器是否存在 sdk 有方法(但是再次没有真正的好处):

const iterator = database.containers.readAll();

const { 资源:containersList } = await iterator.fetchAll();

  1. 创建单例并在第一次初始化所有容器时,下次不要调用它时,确定是否扩展每个实例都会这样做
  2. 我的最爱,使用 terraform/armtemplates/bicep 来启动基础架构,这样您的代码就不需要处理它了

【讨论】:

    【解决方案3】:

    你可以试试这个代码:

    async function check_container_exist(databaseId,containerId) {
        let exist = false;
        const querySpec = {
            query: "SELECT * FROM root r WHERE r.id = @container",
            parameters: [
                {name: "@container", value: containerId}
            ]
        };
        const response = await client.database(databaseId).containers.query(querySpec).fetchNext();
        if(response.resources[0]){
            exist = true;
        }
        return exist;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-08-11
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 2015-09-13
      相关资源
      最近更新 更多