【问题标题】:Get record count in Azure DocumentDb获取 Azure DocumentDb 中的记录数
【发布时间】:2015-01-02 16:36:00
【问题描述】:

在 Azure 站点中的 documentdb 和通过 documentdb 资源管理器 (https://studiodocumentdb.codeplex.com/) 允许的 SQL 查询中,似乎不支持“select count(*) from 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); 

【问题讨论】:

    标签: c# azure azure-cosmosdb


    【解决方案1】:

    这在我们主的 2017 年现在是可能的。

    SELECT VALUE COUNT(1) FROM c

    [ 1234 ]

    【讨论】:

    • 请注意,在上述年份的第 7 个月,这可能会消耗数千个 RU。它也相当慢。
    • 注:单个分区16400条记录消耗535个RU。
    • 相当荒谬的扫描应该是索引的东西需要多少 RU。
    • 在该年的第 9 个月,我仍然依靠 DAL 中自己的逻辑来计算创建/删除事件,因为聚合似乎都是扫描驱动与索引驱动的。
    • @ParthShah - 来自这个 (azure.microsoft.com/en-us/blog/…) 页面:“(如果您想知道 VALUE 关键字 - 所有查询都返回 JSON 片段。通过使用 VALUE,您可以获得标量值计数,例如 100,而不是 JSON 文档 {"$1": 100})"
    【解决方案2】:

    此时实际工作:

    SELECT COUNT(c.id) FROM c
    

    【讨论】:

    • 这给出了不可靠的价值。
    • 这对我不起作用。您需要在 COUNT(c.id) 前面添加 VALUE,就像 Micah Williamson 所说的那样,才能使此查询起作用。
    • 这在使用多个分区时似乎不起作用
    • 它通过添加连续返回的计数值来工作。在这里阅读答案 - stackoverflow.com/questions/47875869/…
    【解决方案3】:

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

    只选择id喜欢的;

      dc.CreateDocumentQuery(update.SelfLink, "SELECT c.id FROM c")
    

    【讨论】:

    • 请注意,Count 现在已实现,如下面的答案所示
    【解决方案4】:

    这可以通过与您现在编写 SQL 查询相同的方式实现,

    SELECT VALUE COUNT(1) FROM myCollection
    

    注意: COUNT(1) 不适用于大型数据集。

    您可以从 here

    了解有关支持的查询的更多信息

    【讨论】:

    • 嗨,请告诉我们如何在不消耗大量 RU 的情况下至少对庞大的数据集进行粗略估计:我说的是可能跨越数十万个分区的数千万或数亿个文档.有没有办法做到这一点?
    【解决方案5】:

    只是回顾一下 - 这里是 Count Stored Procedure via JS 的示例,具有持续支持。

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

    2017 年 3 月更新: 在最新的 DDB SDK 中,请参阅DDB Aggregates press release,它完全支持基本聚合,但没有 GROUP BY(目前)。 这是带有示例的 GIT REpo:https://github.com/arramac/azure-documentdb-dotnet/tree/master/samples/code-samples/Queries

    【讨论】:

      【解决方案6】:

      我对单个分区中包含 200K 实体的分区 Document db 集合进行了测试。集合配置为 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

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

      经过的时间(毫秒):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);
          }
      }
      

      【讨论】:

        【解决方案7】:

        目前不存在。我有一个类似的场景,我们最终为文档属性添加了一个计数器,每次添加或删除文档时都会更新该计数器。如果您想要原子性,您甚至可以将这两个步骤作为存储过程或触发器的一部分。

        【讨论】:

        • 顺便说一句,docdb 产品组正在审查此功能和其他类似功能。你也可以继续投票。 feedback.azure.com/forums/263030-documentdb/suggestions/…
        • 自 2016 年 7 月 29 日起,他们已开始:“我们已开始提供综合支持,并将在获得更多信息后更新此反馈项。”
        【解决方案8】:

        我的代码计数解决方案也有效...一旦我选择了 id 作为 Papa Ours 指出的 :) 要让我的原始帖子正常工作,请替换此行:

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

        用这一行:

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

        我仍然喜欢存储过程的想法,因为它可以在 documentdb 工作室中工作(真的很酷的项目 :))-https://studiodocumentdb.codeplex.com/

        【讨论】:

        • 这会导致更高的 RU
        猜你喜欢
        • 1970-01-01
        • 2018-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        相关资源
        最近更新 更多