Home > Software engineering >  CosmosDb get item by slug
CosmosDb get item by slug

Time:06-16

I am trying to get a single article item from container which is called Articles and it has partition key /slug

public async Task<Article> GetArticle(string slug)
    {
        try
        {
            var response = await _container.ReadItemAsync<Article>(slug, new PartitionKey(slug));
            return response.Resource;
        }
        catch (CosmosException) //For handling item not found and other exceptions
        {
            return null;
        }
    }

This is the link where I got the sample code.

In my case it returns No Content but I am sure there is an article with that slug. I am wondering if the problem has to do with my container or the query?!

CodePudding user response:

ReadItemAsync is using a point lookup - ie, id AND partitionKey

It's basically saying "give me the document with partitionKey x and id x"

I'm going to guess that your Article type looks something like this

public class Item
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "slug")]
    public string Slug { get; set; }
}

Id property is different to slug.

You'll need to either set your id of your document to be slug, or use a query. If slug is immutable, and guaranteed to be unique, it could probably be used for ID.

Point reads using ReadItemAsync only cost 1 RU so are preferable.

Alternatively you'll need to use a query, something along these lines.

var slug = "some-slug";

using (FeedIterator<Article> feedIterator = _container.GetItemQueryIterator<Article>(
    $"select * from Article a where a.slug == {slug}",
    null,
    new QueryRequestOptions { PartitionKey = new PartitionKey(slug)}))
{
    while (feedIterator.HasMoreResults)
    {
        foreach(var item in await feedIterator.ReadNextAsync())
        {
            //do something with Article
        }
    }
}
  • Related