获取Azure DocumentDb中的记录计数

Pro*_*rld 38 c# azure azure-cosmosdb

看来在azure站点中的documentdb允许的SQL查询中以及通过documentdb explorer(https://studiodocumentdb.codeplex.com/)不能支持"从c中选择计数(*)" .到目前为止,获得记录计数的唯一方法是从代码(见下文).但是,我们的集合中有足够的文件,现在崩溃了.有没有办法计算集合中有多少文档比我的解决方案更有效?

DocumentClient dc = GetDocumentDbClient();
var databaseCount = dc.CreateDatabaseQuery().ToList();
Database azureDb = dc.CreateDatabaseQuery().Where(d => d.Id == Constants.WEATHER_UPDATES_DB_NAME).ToArray().FirstOrDefault();

var collectionCount = dc.CreateDocumentCollectionQuery(azureDb.SelfLink).ToList();

DocumentCollection update = dc.CreateDocumentCollectionQuery(azureDb.SelfLink).Where(c => c.Id == "WeatherUpdates").ToArray().FirstOrDefault();

var documentCount = dc.CreateDocumentQuery(update.SelfLink, "SELECT * FROM c").ToList();

MessageBox.Show("Databases: " + databaseCount.Count().ToString() + Environment.NewLine
                +"Collections: " + collectionCount.Count().ToString() + Environment.NewLine
                + "Documents: " + documentCount.Count().ToString() + Environment.NewLine, 
                 "Totals", MessageBoxButtons.OKCancel); 
Run Code Online (Sandbox Code Playgroud)

mic*_*cah 97

现在,我们的主人可以在2017年实现这一目标.

SELECT VALUE COUNT(1) FROM c

[ 1234 ]

  • 请注意,在所述年份的第7个月,这可能会吞噬数千个RU.它也很慢. (29认同)
  • 扫描一些应该是索引的东西需要多少RU才是荒谬的. (15认同)
  • 在所述年份的第9个月,我仍然依靠自己在DAL中的逻辑来计算创建/删除事件,因为聚合似乎都是扫描驱动和索引驱动. (6认同)
  • 注意:单个分区中的16,400条记录消耗535个RU. (4认同)
  • @ParthShah - 从这里(https://azure.microsoft.com/en-us/blog/planet-scale-aggregates-with-azure-documentdb/)页面:"(如果你想知道VALUE关键字 - 所有查询返回JSON片段.通过使用VALUE,您可以获得count的标量值,例如100,而不是JSON文档{"$ 1":100})" (3认同)
  • 你能解释为什么我需要在我的查询中添加VALUE吗?我习惯写"从c中选择计数(*)"和"从c中选择计数(1)"非常相似. (2认同)
  • 所以 azure 的门户会撒谎并说 0 RU。F12 并查看调用,在 c# 客户端中看到完全相同的内容。它进行一次调用失败 (400),然后进行第二次调用失败,然后将查询修改为 SELECT VALUE [{"item": COUNT(1)}] FROM c,这会导致行扫描。但最好的部分是他们的 UI 显示第一个失败查询的 RU 计数为 0。 (2认同)

小智 24

实际上在这一点上工作:

SELECT COUNT(c.id)FROM c

  • 这给出了不可靠的价值. (5认同)
  • 这对我不起作用。您需要在 COUNT(c.id) 前面添加 VALUE,就像 Micah Williamson 所说的那样,此查询才能工作。 (2认同)

小智 10

在执行"count"关键字之前,您应该在服务器上的存储过程中进行查询.如果您只想计算,请注意不要在查询中获取所有列/属性.

只选择id;

  dc.CreateDocumentQuery(update.SelfLink, "SELECT c.id FROM c")
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“Count”现已实现,如下面的答案所示 (2认同)

zmi*_*che 9

回顾一下 - 这里是通过JS继续支持的Count存储过程的示例.

这里还有一个非常简洁的DocumentDb工具:https://github.com/mingaliu/DocumentDBStudio/releases

Upd 20173月:在最新的DDB SDK中,请参阅DDB Aggregates新闻稿,完全支持基本聚合,但没有GROUP BY(现在).这是GIT REpo的例子:https://github.com/arramac/azure-documentdb-dotnet/tree/master/samples/code-samples/Queries


Saj*_*ran 7

这与您现在编写SQL查询的方式相同,

SELECT VALUE COUNT(1) FROM myCollection
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

注意: COUNT(1)不适用于庞大的数据集.

您可以从此处详细了解支持的查询


Dog*_*lan 6

我对单个分区中包含 20 万个实体的分区文档数据库集合进行了测试。集合配置为 10K RU/秒。

客户端查询:

  1. "SELECT VALUE COUNT(1) FROM c"

已用时间(毫秒):2471 毫秒消耗的总请求单位:6143.35

注意:这是最快和最便宜的选择。但请记住,您需要在客户端处理延续并使用返回的延续令牌执行下一个查询,否则您可能会得到部分结果/计数。

  1. "SELECT COUNT(c.id) FROM c"

已用时间(毫秒):2589 总 RU:6682.43

注意:这非常接近,但速度稍慢且价格更高。

服务器端/存储过程:

  1. 如果你需要一个存储过程,这里提供了一个:https : //github.com/Azure/azure-cosmosdb-js-server/blob/master/samples/stored-procedures/Count.js

但要注意这是有问题的。它在内部读取集合/分区中的所有文档只是为了计算计数。结果,它慢得多,而且贵得多!

已用时间 (ms):8584 毫秒总 RU:13419.31

  1. 我更新了上面链接中提供的存储过程以提高性能。下面是完整更新的 Count.js。更新后的存储过程比原始过程执行得更快、成本更低,并且与性能最佳的客户端查询(上面的#1)相当:

已用时间(毫秒):2534 毫秒总 RU:6298.36

function count(filterQuery, continuationToken) {
    var collection = getContext().getCollection();
    var maxResult = 500000; 
    var result = 0;

    var q = 'SELECT \'\' FROM root';
    if (!filterQuery) {
        filterQuery = q;
    }

    tryQuery(continuationToken);

    function tryQuery(nextContinuationToken) {
        var responseOptions = { continuation: nextContinuationToken, pageSize: maxResult };

        if (result >= maxResult || !query(responseOptions)) {
            setBody(nextContinuationToken);
        }
    }

    function query(responseOptions) {
        return (filterQuery && filterQuery.length) ?
            collection.queryDocuments(collection.getSelfLink(), filterQuery, responseOptions, onReadDocuments) :
            collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);
    }

    function onReadDocuments(err, docFeed, responseOptions) {
        if (err) {
            throw 'Error while reading document: ' + err;
        }

        result += docFeed.length;

        if (responseOptions.continuation) {
            tryQuery(responseOptions.continuation);
        } else {
            setBody(null);
        }
    }

    function setBody(continuationToken) {
        var body = { count: result, continuationToken: continuationToken };
        getContext().getResponse().setBody(body);
    }
}
Run Code Online (Sandbox Code Playgroud)