![](/img/trans.png)
[英]Azure Function HTTP trigger to receive nested JSON and store in Cosmos DB
[英]Integrating Cosmos DB with OData using Azure Http trigger function app
目標:實現 oData Azure Http 觸發器功能以減少延遲。
我在 cosmosdb 中缺少 3.5 記錄並使用 azure Http Trigger 函數應用程序查詢數據。
我正在通過 azure Http Trigger Function 中的 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 觸發功能應用程序
您提供的鏈接僅適用於“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;
}
我能想象你能做到的唯一方法是使用EF Core For Cosmos DB
那么您可以將Azure Functions OData 擴展與 IQueryable 結合使用。
有了它,您應該讓 EF Core 直接在 CosmosDB 中為您提供特定的選擇。
但這只有在您從一開始就將 EF Core 與 Cosmos DB 一起使用時才有效,因為 EF Core 對 Cosmos DB 中的 PK、Id 和鑒別器具有特定的格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.