当我只需要计数而不读取 Document-Db 数据库中的所有文档时,如何使用 Linq 构造 IQueryable 查询?
Posted
技术标签:
【中文标题】当我只需要计数而不读取 Document-Db 数据库中的所有文档时,如何使用 Linq 构造 IQueryable 查询?【英文标题】:How to construct IQueryable query using Linq when I just need count without reading all documents in Document-Db database? 【发布时间】:2017-12-24 07:18:46 【问题描述】:我需要存储在 Azure Cosmos Db 数据库中的集合中的文档数。如何使用IQueryable
对象上的 LINQ 查询获得计数?
docDbClient.CreateDocumentQuery<TResult>().Count()
如果我按照上述方式进行操作,我将无法使用.AsDocumentQuery()
方法跟进。
【问题讨论】:
Count
返回一个整数 - 你为什么要跟随想要处理“一组”项目的东西?
还有一件事....DocumentDB API 原生支持Count
查询。您应该尝试使用它而不是这样计数。
那么,在这种情况下,我必须自己构造 SQL 语句,而不是使用 LINQ 提供程序?
您的查询应该已经完全符合您的要求 - 获取计数而不检索其他任何内容。
但是要将这个 IOrderedQueryable 与 Document-DB 一起使用,我必须调用 AsDocumentQuery(),对吧?
【参考方案1】:
这是我的异步实现(使用 Count,用于同步版本):
var count = await DocumentClient.
CreateDocumentQuery<T>(CreateCollectionUri(), CreateFeedOptions()).
Where(predicate).
CountAsync();
谓词是Expression<Func<T, bool>>
【讨论】:
【参考方案2】:您可以尝试使用以下代码来统计您的集合中的文档数。
client = new DocumentClient(new Uri(EndpointUri), PrimaryKey);
IQueryable<int> total = client.CreateDocumentQuery<int>(UriFactory.CreateDocumentCollectionUri("testdb", "testcoll"), "SELECT Value count(1) FROM c", new FeedOptions() EnableCrossPartitionQuery = true );
Console.WriteLine("total: " + total.AsEnumerable().FirstOrDefault());
查询结果:
如果您捕获请求(使用 fiddler 等),您会发现客户端 sdk 在执行代码 docDbClient.CreateDocumentQuery<TResult>().Count()
时向服务器发送相同的查询 "query":"SELECT VALUE [\"item\": Count(1)]\r\nFROM root"
。
【讨论】:
【参考方案3】:实现这一目标的另一种方法是:
using Microsoft.Azure.Cosmos.Linq; // required for CountAsync()
//...
cosmosClient
.GetContainer(databaseName, containerName)
.GetItemLinqQueryable<MyRecord>(true)
.Where(r => r.Name == "John")
.Where(r => r.Status == MyRecordStatus.Approved)
.CountAsync()
【讨论】:
您允许同步执行是否有任何具体原因 (.GetItemLinqQueryable<MyRecord>(true)
)?
是的,我现在想不起来了,但是我测试了它并且由于某种原因没有工作。故意使用同步执行。以上是关于当我只需要计数而不读取 Document-Db 数据库中的所有文档时,如何使用 Linq 构造 IQueryable 查询?的主要内容,如果未能解决你的问题,请参考以下文章
SQL 使用 group_concat 与每个连接项目的计数,而不是在一行中的总计数
GMUClusterRendererDelegate 仅在渲染集群时才显示标记图标视图,而不是在该 swift 5 之前