如何允许将 Odata 选项应用于 cosmos db 集合并返回过滤后的记录
Posted
技术标签:
【中文标题】如何允许将 Odata 选项应用于 cosmos db 集合并返回过滤后的记录【英文标题】:How to allow Odata options to be applied to cosmos db collection and return filtered records 【发布时间】:2020-11-30 05:10:15 【问题描述】:我需要在 api 上实现分页。我正在执行以下操作以在 api 上启用 OData 查询,但它在从 cosmos db 获取所有记录后进行过滤,但我想从 cosmos db 中获取过滤后的记录。如何将 Odata 查询选项转换为 cosmos db 查询选项?
controller.cs
[Route("apps")]
[HttpGet]
[EnableQuery]
public async Task<IActionResult> GetAllApps(CancellationToken cancellationToken)
var user = this.GetUser();
var results = await this.appRepository.GetAppsForUserAsync(user, cancellationToken).ConfigureAwait(false);
return this.Ok(this.mapper.Map<AppHeader[]>(results));
AppRepository.cs
public async Task<IEnumerable<App>> GetAppsForUserAsync(User user, CancellationToken cancellationToken)
try
FeedOptions queryOptions = new FeedOptions
MaxItemCount = -1,
PartitionKey = new PartitionKey(user)
;
var query = this.factory.GetClient()
.CreateDocumentQuery<App>(
UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
queryOptions)
.Where(resource => resource.UserList.Any(u => u.userId == user.Id))
.AsDocumentQuery();
List<App> results = new List<App>();
while (query.HasMoreResults)
cancellationToken.ThrowIfCancellationRequested();
var response = await query.ExecuteNextAsync<App>(cancellationToken).ConfigureAwait(false);
var app = this.mapper.Map<App[]>(response);
results.AddRange(app);
return results;
catch (DocumentClientException ex)
this.logger.LogError(ex, ex.Message);
throw;
Client.js
http://localhost:8303/api/appdefinitions/my?$skip=6&$top=4`
【问题讨论】:
【参考方案1】:在存储库中,尝试使用GetItemLinqQueryable 并对其进行查询。请注意,我在这里使用的是较新的 V3 SDK Microsoft.Azure.Cosmos,但旧版 SDK 中也应该存在等效项。
// Take `skip` and `top` params as input to the repository method.
List<App> results = new List<App>();
using (CosmosClient client = new CosmosClient(endpoint, authKey))
Database cosmosDatabase = await client.CreateDatabaseIfNotExistsAsync(DatabaseName);
Container container = await Program.GetOrCreateContainerAsync(cosmosDatabase, CollectionName);
// LINQ query generation
using (FeedIterator setIterator = container.GetItemLinqQueryable<App>()
.Where(a => a.userId == user.Id)
.Skip(skip)
.Take(top)
.ToFeedIterator())
//Asynchronous query execution
while (setIterator.HasMoreResults)
var items = await feedIterator.ReadNextAsync().ConfigureAwait(false);
results.AddRange(items);
注意:理想情况下,在实际应用程序中,您应该重用 CosmosClient
实例,而不是每次都为 performance improvement 创建。
【讨论】:
感谢您的回答!。我会考虑这一点,但是如何将 skip 和 top 参数作为输入传递给存储库方法?如何建模从客户端到控制器的绑定跳过和顶部? 您可以通过控制器操作绑定到ODataQueryOptions 模型。 我同意您的选择,但就我而言,我想在不使用更新的 V3 SDK Microsoft.Azure.Cosmos 的情况下实现该功能以上是关于如何允许将 Odata 选项应用于 cosmos db 集合并返回过滤后的记录的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Azure 虚拟网络从 power bi 桌面应用程序连接到 cosmos db
如何使用 Cassandra API 将 Python 的 cosmos_client 连接到 Cosmos DB 实例?