当前位置: 首页 > 知识库问答 >
问题:

使用Azure Http触发函数应用程序集成Cosmos DB和OData

何琨
2023-03-14

我正在azure Http触发器函数中通过azure DocumentDB客户端查询CosmosDB数据。

        public static async Task<IActionResult> MachinesByRegion_Get(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "Region/Machines")]HttpRequest req,
        ILogger log)
    {

        log.LogInformation("GetMachinesByRegion function Started to process a request.");

        // check parameters
        if (string.IsNullOrEmpty(req.Query["PageSize"]) || string.IsNullOrEmpty(req.Query["PageNumber"]))
            return new BadRequestObjectResult(new PostActionResponse(400, "Please provide valid PageSize and PageNumber"));

        // Number of documents per page
        int pageSize = int.Parse(req.Query["PageSize"]);
        Dictionary<string,string> field = new Dictionary<string, string>();
        string columns = "*";
        if (!string.IsNullOrEmpty(req.Query["Fields"]))
        {
            string columnstring = req.Query["Fields"].ToString();
            field.Add("Fields", columnstring);
            string[] columnarr = columnstring.Split(',');
            int arraylength = columnarr.Length;

            // Build Selection columns
            if (arraylength != 0)
            {
                StringBuilder strinbuilder = new StringBuilder("c.id, ");
                int i = 1;
                foreach (string value in columnarr)
                {
                    strinbuilder.Append($"c.{value.Replace(" ", String.Empty)}");
                    if (arraylength > i)
                        strinbuilder.Append(", ");
                    i++;
                }
                columns = strinbuilder.ToString();
            }
        }

        // Parse Query Parameter
        int pagenumber = int.Parse(req.Query["PageNumber"]);

        int offset = pagenumber == 1 ? 0 : (pagenumber - 1) * pageSize;

        // Bulid query string based on request
        string sqlstr = string.Format($"SELECT {columns} FROM c ORDER BY c.id ASC OFFSET {offset} LIMIT {pageSize}");


        Helper.TraceLogWriter(log, "Summary:");
        Helper.TraceLogWriter(log, "--------------------------------------------------------------------- ");
        Helper.TraceLogWriter(log, $"Collection : {DBConstants.DataBaseName.Telemetry}.{DBConstants.ContainerName.KomatsuMachine}");
        Helper.TraceLogWriter(log, $"The Query String : {sqlstr}");
        Helper.TraceLogWriter(log, "--------------------------------------------------------------------- ");
        Helper.TraceLogWriter(log, "");

        try
        {
            // Feed Options 
            var options = new FeedOptions
            {
                MaxItemCount = pageSize,
                MaxDegreeOfParallelism = -1,
                EnableCrossPartitionQuery = true,
            };

            // Create CosmosDB Connection URI
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId: DBConstants.DataBaseName.Telemetry, collectionId: DBConstants.ContainerName.KomatsuMachine);

            ConnectionPolicy connPolicy = new ConnectionPolicy
            {
                ConnectionMode = ConnectionMode.Direct,
                ConnectionProtocol = Protocol.Tcp
            };

            using var client = new DocumentClient(new Uri(BaseRepository.EndpointUri), BaseRepository.PrimaryKey, connPolicy);
            // Get the List of Items against the Query string
            var results = client.CreateDocumentQuery(collectionUri, sqlstr, options).ToList();
            int records = results.Count;
            Helper.TraceLogWriter(log, $"Retrieved Documents: {records}");

            Helper.TraceLogWriter(log, $"Sample Document: {JsonConvert.DeserializeObject(JsonConvert.SerializeObject(results[0]))}");

            await Task.Yield();

            // Build base url                    
            var pages = new PageLinkBuilder($"{BaseRepository.BaseUrl}/api/Region/Machines", pagenumber, pageSize, records, field);

            return (ActionResult)new OkObjectResult(new PagedResult
            {
                PageNumber = pagenumber,
                PageSize = records,
                Pages = pages,
                Results = results
            });
        }
        catch (Exception ex)
        {
            Helper.TraceErrorWriter(log, $"Exception caught in GetMachinesByProduct: {ex.Message}");
            return new UnprocessableEntityObjectResult(new PostActionResponse(422, "Exception in CosmosDB, Please check logs"));
        }
    }

我只想让oData在选择、筛选和排序等情况下具有乐观的性能。

在cosmosDB中,文档有很多字段,如果启用,会减少数据的大小。

这是针对Web API的。但我需要azure Http触发功能的应用程序

共有1个答案

公冶俊达
2023-03-14

您提供的链接仅针对“where”谓词,它根本不会减少选择,因为它是IEnumerable而不是IQueryable:

public async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate)
    {
        IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
            UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
            new FeedOptions { MaxItemCount = -1 })
            .Where(predicate)
            .AsDocumentQuery();

        List<T> results = new List<T>();
        while (query.HasMoreResults)
        {
            results.AddRange(await query.ExecuteNextAsync<T>());
        }

        return results;
    }

我能想象的唯一方法是使用Cosmos DB的EF核心

然后可以使用Azure函数OData扩展和IQueryable。

 类似资料:
  • 让spring集成应用程序具有入站http网关和出站http网关,在我想要缓存的两个网关之间,以避免不必要的请求。我唯一的解决方案是在它之后添加带缓存的拦截器和路由器,将cahced结果路由回回复通道,而非缓存的路由回出站,但这个解决方案对我来说似乎很棘手和丑陋。当入站网关具有相同的请求和应答通道时,带缓存的拦截器也可以正常工作(当返回具有相同标头但不同负载的新消息时,它被视为应答),但我不能使用

  • 在本节中,介绍了在MySQL 5.1中使用触发程序的方法,并介绍了在使用触发程序方面的限制。 触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。在某些触发程序的用法中,可用于检查插入到表中的值,或对更新涉及的值进行计算。 触发程序与表相关,当对表执行INSERT、DELETE或UPDATE语句时,将激活触发程序。可以将触发程序设置为在执行语句之前或之后激活。例如,可以在从表中

  • 在Azure中,我开发了一个函数(应用服务),当新的csv文件放入特定存储帐户时会触发该函数。该函数是在Azure中开发的,每次上传新的csv文件时都不会出现问题。但是考虑到CI/CD,我决定将我的开发过程从Azure迁移到Visual Studio(2017)。 代码在本地运行没有任何问题,但一旦我将代码发布到Azure(通过VSTS),挑战就开始了。当新的csv文件上传到存储帐户时,触发器似乎

  • 我已将 Azure 函数设置为运行 Blob 触发器,(因此,当将 Blob 添加到容器时,它应该触发)。在门户中打开函数应用之前,函数不会运行。然后,它将拾取已添加的任何 blob 并像往常一样处理它们。为什么需要在门户中打开函数应用才能启动我的作业?这几乎就像函数应用程序进入睡眠状态,然后在我浏览到它时唤醒。我该如何防止这种情况发生? 这是我的克朗

  • 我试图了解ApacheShiro工作流以及如何将其集成到我的应用程序中。我不明白的是,我如何以及在哪里执行登录,然后发送重定向?或者Shiro会自动执行此操作(因为我在ini文件中指定了域)?我可以发送自定义信息(用户属性)和重定向(通过Servlet响应而不是支持bean)吗? 到目前为止我所了解和拥有的: 将Shiro侦听器和过滤器添加到web。xml文件,以便它能够响应请求: 创建一个shi

  • 我将JSON文档上传到Azure Blob容器中,并编写了Azure Python函数将JSON写入CosmosDB。触发工作正常,但我出错了。下面是Python函数: 以下是function.json文件: 这是我在Azure门户中看到的错误: 结果:失败异常:函数加载错误:无法加载JsonBobTrigger1函数:以下参数在Python中声明,但在function.json中没有声明:{'d