当我只需要计数而不读取 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&lt;Func&lt;T, bool&gt;&gt;

【讨论】:

【参考方案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&lt;TResult&gt;().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&lt;MyRecord&gt;(true))? 是的,我现在想不起来了,但是我测试了它并且由于某种原因没有工作。故意使用同步执行。

以上是关于当我只需要计数而不读取 Document-Db 数据库中的所有文档时,如何使用 Linq 构造 IQueryable 查询?的主要内容,如果未能解决你的问题,请参考以下文章

当我只需要知道是不是超过 1 时,如何优化获取结果计数?

检查数据框中的记录数是不是大于零而不使用计数火花

SQL 使用 group_concat 与每个连接项目的计数,而不是在一行中的总计数

GMUClusterRendererDelegate 仅在渲染集群时才显示标记图标视图,而不是在该 swift 5 之前

如何使用 SwiftUI DocumentGroup 读取大文件而不制作临时副本?

如何在C中使用pthread_join来控制线程数?