如何使用节点sdk检查cosmos DB中是否存在容器



我想检查一个容器是否存在,如果不存在,初始化它

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

但这似乎不是正确的做法

任何帮助都将不胜感激!

我不太清楚为什么需要这样做,因为在应用程序实例的生命周期中,通常只需要做一次这种事情。但我不建议这样做。

当您查询Cosmos以测试数据库、容器等的存在性时,这会命中帐户的主分区。主分区有点像一个小小的Cosmos数据库,里面有你所有的账户元数据

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

如果有某种方法可以设计它,使它不必查询容器的存在,那么我会转而追求它。

有趣的问题。所以我认为你有几个选择

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

const迭代器=数据库.容器.读取所有((;

const{resources:containersList}=等待迭代器.fetchAll((;

  1. 创建singleton,第一次只初始化所有容器,所以下次不调用它时,确保如果扩展每个实例,也会执行相同的操作
  2. 我最喜欢的是,使用terraform/armtemplates/bicep来旋转基础设施,这样代码就不需要处理它了

您可以尝试以下代码:

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

最新更新