5

From the docs I understand that I can query a CosmosDB by specifying a query in the attribute like so:

public static class DocByIdFromRouteDataUsingSqlQuery
{
    [FunctionName("DocByIdFromRouteDataUsingSqlQuery")]
    public static IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", 
            Route = "todoitems2/{id}")]HttpRequest req,
        [CosmosDB("ToDoItems", "Items",
            ConnectionStringSetting = "CosmosDBConnection",
            SqlQuery = "select * from ToDoItems r where r.id = {id}")]
            IEnumerable<ToDoItem> toDoItems,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        foreach (ToDoItem toDoItem in toDoItems)
        {
            log.LogInformation(toDoItem.Description);
        }

        return new OkResult();
    }
}

But I don't want to setup a query in my attribute. I want to do that in the method. I want to do some if/else checks before I do a query to my CosmosDB.

I can't find any examples where to use something like a CosmosDbClient. Does such a thing exist?

So basically my question is, how can I run a query from inside my method instead of inside the attribute?

2

2 Answers 2

1

A simple code to acheive your requirement:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Azure.Cosmos;

namespace FunctionApp2
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            CosmosClient cosmosClient = new CosmosClient(Program.EndpointUrl, Program.AuthorizationKey);
            bool test = await QueryItemsAsync(cosmosClient);
            string a = "this is ...";
            if (test == true)
            {
                a = "Find the object.";
            }
            else {
                a = "Not find the object.";
            }
            return new OkObjectResult(a);
        }

        public static class Program
        {
            public const string EndpointUrl = "https://testbowman.documents.azure.com:443/";
            public const string AuthorizationKey = "KIOWEDdQQogxxxxxxcNRnPbsg==";

            public const string DatabaseId = "testbowman";
            public const string ContainerId = "testbowman";
        }
        private static async Task<bool> QueryItemsAsync(CosmosClient cosmosClient)
        {
            var sqlQueryText = "SELECT * FROM c WHERE c.LastName = 'Bowman'";

            Console.WriteLine("Running query: {0}\n", sqlQueryText);

            CosmosContainer container = cosmosClient.GetContainer(Program.DatabaseId, Program.ContainerId);

            QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText);

            List<Family> families = new List<Family>();

            await foreach (Family family in container.GetItemQueryIterator<Family>(queryDefinition))
            {
                families.Add(family);
                Console.WriteLine("\tRead {0}\n", family);
            }

            if (families.Count > 0)
            {
                return true;
            }
            else {
                return false;
            }
        }
    }
}

And this is the doc:

https://learn.microsoft.com/en-us/azure/cosmos-db/create-sql-api-dotnet-v4#query-the-items

Sign up to request clarification or add additional context in comments.

1 Comment

This example has a big flaw, it is creating the CosmosClient inside the Run method, please do not do so, it can cause connection issues: learn.microsoft.com/en-us/azure/azure-functions/…
1

You can easily achieve this by pulling the DocumentClient from the Input Binding like so:

public static class DocByIdFromRouteDataUsingSqlQuery
{
    [FunctionName("DocByIdFromRouteDataUsingSqlQuery")]
    public static IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", 
            Route = "todoitems2/{id}")]HttpRequest req,
        [CosmosDB("ToDoItems", "Items",
            Connection= "CosmosDBConnection"]
            CosmosClient client,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        if (someLogic){
            var container = client.GetContainer("MyDatabase","MyContainer");
            using var iterator = container.GetItemQueryIterator<ToDoItems>(
                new QueryDefinition("select * from ToDoItems r where r.id = @id")
                   .WithParameter("@id", "SomeValue"));
            while (iterator.HasMoreResults())
            {
              .. consume the query
            }
        }
        else{
            // do a different query
        
        }

        return new OkResult();
    }
}

Update:

DocumentClient is now deprecated in latest version, the example now uses CosmosClient

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.