简体   繁体   中英

How to check if a container exists in cosmos DB using the node sdk?

I want to check if a container exists and if not, initialize it. I was hoping for something like the following:

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
}

The reason I'm not using "createIfNotExists" is because I would need to make a 2nd call to check if the container returned is populated with items or not. The container I'm creating is going to hold settings data which will be static once the container is initially created. This settings check is going to happen per request so I'd like to minimize the database calls and operations if possible.

I tried doing something like:

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

But that doesn't seem like the right way to do it.

Any help would be appreciated!

I'm not quite clear on why you would need to do this since typically you only need to do this sort of thing once for the life of your application instance. But I would not recommend doing it this way.

When you query Cosmos to test the existence of a database, container, etc., this hits the master partition for the account. The master partition is kind of like a tiny Cosmos database with all of your account meta data in it.

This master partition is allocated a small amount of the RU/s that manage the metadata operations. So if you app is designed to make these types of calls for every single request, it's quite likely you will get rate limited in your application.

If there is some way you can design this such that it doesn't have to query for the existence of a container then I would pursue that instead.

Interesting question. So i think you have few options

  1. Just call const { container } = await database.containers.createIfNotExists({ id: "Container" }); it will be fast probably few milliseconds, since I went via code at looks like it will always try to read from cosmos:( If you want to still check if container exists sdk has methods(But again no real benefits ):

const iterator = database.containers.readAll();

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

  1. Create singleton and first time just initialise all your containers so next time you dont call it, sure if you scale each instance will do the same
  2. My favourite, use terraform/armtemplates/bicep to spin up infrastructure so you code wont need to handle that

You can try this code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM