Azure用Cosmos DB绑定功能 - 订单在以路线参数为路线时不工作

发布于 2025-02-13 20:17:30 字数 2524 浏览 0 评论 0 原文

我正在尝试从特定字段订购的容器中获取项目列表。

这是我的cosmosdb与SQL查询绑定:

[FunctionName("FilterEvents")]
public static IActionResult FilterEvents(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "events/{PartitionKey}/{Order}/{SearchTerm}")] HttpRequest req,
    [CosmosDB(
            databaseName: Constants.DatabaseName,
            collectionName: Constants.ContainerName,
            ConnectionStringSetting = "CosmosDBConnectionString",
            SqlQuery = "SELECT * " +
                "FROM c " +
                "WHERE c.email = {PartitionKey} AND CONTAINS(c.title, {SearchTerm})" +
                "ORDER BY c.participantsCount {Order}"
        )] IEnumerable<Event> events,
    string PartitionKey,
    string Order,
    string SearchTerm,
        ILogger log)
{
   ...
   Console.WriteLine(PartitionKey);
   Console.WriteLine(Order);
   Console.WriteLine(SearchTerm);
}

当我使用此参数调用此API时:

https://../api/events/ [email&nbsp; procearted] /asc/asc/event

以下错误:

System.Private.CoreLib: Exception while executing function: FilterEvents. 
Microsoft.Azure.WebJobs.Host: Exception binding parameter 'events'.
Microsoft.Azure.DocumentDB.Core: Message: 
{
 "errors":[
 { 
  "severity":"Error",
  "location": {
    "start":101,
    "end":107},
    "code":"SC1001",
    "message":"Syntax error, incorrect syntax near '@Order'."
  }
 ]
}
[2022-07-07T13:49:53.666Z] ActivityId: 2a1a4919-f6e9-4b10-81b3-2ff2aa9d0159, Microsoft.Azure.Documents.Common/2.14.0, Windows/10.0.22621 documentdb-netcore-sdk/2.13.1.

收到 ,从c中选择 * c.email = {partitionKey}并包含(c.Title,{searchTerm})

并使用相同的URL参数调用, https://.. //../api/events/ [email&nbsp; procearted] /asc/asc/event

我什至可以看到在console中打印的值

   Console.WriteLine(PartitionKey); // [email protected]
   Console.WriteLine(Order);        // ASC
   Console.WriteLine(SearchTerm);   // event

:或“ desc”代替 {order} ,事情只是工作预计,

我找不到任何建议

I'm trying to fetch a list of items from a container ordered by a specific field.

Here's my CosmosDB Binding with SQL Query:

[FunctionName("FilterEvents")]
public static IActionResult FilterEvents(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "events/{PartitionKey}/{Order}/{SearchTerm}")] HttpRequest req,
    [CosmosDB(
            databaseName: Constants.DatabaseName,
            collectionName: Constants.ContainerName,
            ConnectionStringSetting = "CosmosDBConnectionString",
            SqlQuery = "SELECT * " +
                "FROM c " +
                "WHERE c.email = {PartitionKey} AND CONTAINS(c.title, {SearchTerm})" +
                "ORDER BY c.participantsCount {Order}"
        )] IEnumerable<Event> events,
    string PartitionKey,
    string Order,
    string SearchTerm,
        ILogger log)
{
   ...
   Console.WriteLine(PartitionKey);
   Console.WriteLine(Order);
   Console.WriteLine(SearchTerm);
}

When I invoke this API with this parameters:

https://../api/events/[email protected]/ASC/event

I get the following error: :(

System.Private.CoreLib: Exception while executing function: FilterEvents. 
Microsoft.Azure.WebJobs.Host: Exception binding parameter 'events'.
Microsoft.Azure.DocumentDB.Core: Message: 
{
 "errors":[
 { 
  "severity":"Error",
  "location": {
    "start":101,
    "end":107},
    "code":"SC1001",
    "message":"Syntax error, incorrect syntax near '@Order'."
  }
 ]
}
[2022-07-07T13:49:53.666Z] ActivityId: 2a1a4919-f6e9-4b10-81b3-2ff2aa9d0159, Microsoft.Azure.Documents.Common/2.14.0, Windows/10.0.22621 documentdb-netcore-sdk/2.13.1.

=> When I simply remove that ORDER BY clause from my SQL Query,

i.e, SELECT * FROM c WHERE c.email = {PartitionKey} AND CONTAINS(c.title, {SearchTerm})

and invoke with the same URL Parameters, https://../api/events/[email protected]/ASC/event

I could even see the values getting printed in the console:

   Console.WriteLine(PartitionKey); // [email protected]
   Console.WriteLine(Order);        // ASC
   Console.WriteLine(SearchTerm);   // event

=> Also, when I hardcode the value 'ASC' or 'DESC' in place of {Order}, things just work as expected.

I couldn't find any information on why this is not working. Any suggestion would be much helpful here.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜尕妞 2025-02-20 20:17:30

看起来不受支持。如果您查看实现在这里,它正在转换查询参数到SQL参数:

foreach (var parameter in attribute.SqlQueryParameters)
{
    queryDefinition.WithParameter(parameter.Item1, parameter.Item2);
}

这与子句的顺序无法使用。

或者,您可以使用 documentclient 绑定,但是您必须自己编写查询:

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 System.Collections.Generic;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Microsoft.Azure.Documents;
...
[FunctionName("FilterEvents")]
public static async Task<IActionResult> FilterEventsAsync(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "events/{PartitionKey}/{Order}/{SearchTerm}")] HttpRequest req,
    [CosmosDB(ConnectionStringSetting = "CosmosDBConnectionString")] DocumentClient client,
    string PartitionKey,
    string Order,
    string SearchTerm,
    ILogger log)
{
    var querySpec = new SqlQuerySpec(
        $"SELECT * FROM c WHERE c.email = @PartitionKey AND CONTAINS(c.title, @SearchTerm) ORDER BY c.participantsCount {Order}"
        , new SqlParameterCollection(new[] { 
            new SqlParameter("@PartitionKey", PartitionKey)
            , new SqlParameter("@SearchTerm", SearchTerm)
        })
    );

    var collectionUri = UriFactory.CreateDocumentCollectionUri(Constants.DatabaseName, Constants.ContainerName);
    IDocumentQuery<Event> query = client.CreateDocumentQuery<Event>(collectionUri, querySpec)
        .AsDocumentQuery();

    var events = new List<Event>();
    while (query.HasMoreResults)
    {
        foreach (Event result in await query.ExecuteNextAsync())
        {
            events.Add(result);
        }
    }

    return new OkObjectResult(events);
}

老实说,不确定是否会更糟。如果您知道查询不会返回太多项目,则可以通过子句对该订单的默认值进行编程恢复:

events.Reverse();
return new OkObjectResult(events);

它将允许您保留现有的实现。

It doesn't looks like it is supported. If you look at the implementation here, it is converting the query parameters into SQL parameters:

foreach (var parameter in attribute.SqlQueryParameters)
{
    queryDefinition.WithParameter(parameter.Item1, parameter.Item2);
}

This won't work with ORDER BY clause.

Alternatively, you could use the DocumentClient binding but then you'll have to write the query yourself:

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 System.Collections.Generic;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Microsoft.Azure.Documents;
...
[FunctionName("FilterEvents")]
public static async Task<IActionResult> FilterEventsAsync(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "events/{PartitionKey}/{Order}/{SearchTerm}")] HttpRequest req,
    [CosmosDB(ConnectionStringSetting = "CosmosDBConnectionString")] DocumentClient client,
    string PartitionKey,
    string Order,
    string SearchTerm,
    ILogger log)
{
    var querySpec = new SqlQuerySpec(
        
quot;SELECT * FROM c WHERE c.email = @PartitionKey AND CONTAINS(c.title, @SearchTerm) ORDER BY c.participantsCount {Order}"
        , new SqlParameterCollection(new[] { 
            new SqlParameter("@PartitionKey", PartitionKey)
            , new SqlParameter("@SearchTerm", SearchTerm)
        })
    );

    var collectionUri = UriFactory.CreateDocumentCollectionUri(Constants.DatabaseName, Constants.ContainerName);
    IDocumentQuery<Event> query = client.CreateDocumentQuery<Event>(collectionUri, querySpec)
        .AsDocumentQuery();

    var events = new List<Event>();
    while (query.HasMoreResults)
    {
        foreach (Event result in await query.ExecuteNextAsync())
        {
            events.Add(result);
        }
    }

    return new OkObjectResult(events);
}

To be honest, not sure if it worse it. If you know the query won't returned too many items, you could have a default value for the order by clause and revert it programmatically:

events.Reverse();
return new OkObjectResult(events);

It will allow you to keep your existing implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文