如何计算所有文档,azure DocumentDB

时间:2016-07-26 07:59:55

标签: .net azure azure-cosmosdb

下一个SP是对集合中所有文档进行计数的豁免,并且通常学习如何处理完整的集合。

由于某种原因,下一个SP返回

  

{"计数":0," QueryCount":0}

虽然我希望它能够回归

  

{" count":1000," QueryCount":1}

SP:

   function CountAll(continuationToken) {
    var collection = getContext().getCollection();
    var results =0;
    var queryCount = 0;
    var pageSize = 1000;
    var responseOptionsContinuation;
    var accepted = true;

    var responseOptions = { continuation: continuationToken, pageSize : pageSize};

    if (accepted) {
        accepted = collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);
        responseOptions.continuation = responseOptionsContinuation;
    }
    setBody();



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

        results += docFeed.length;
        responseOptionsContinuation = responseOptions.continuation;
    }

    function setBody() {
        var body = { count: results,  QueryCount: queryCount};
        getContext().getResponse().setBody(body);
    }
}

2 个答案:

答案 0 :(得分:5)

请注意,DocumentDB现在将文档总数作为标题返回。 您可以通过调用GET / colls / collectionName(.NET中的ReadDocumentCollectionAsync)将其作为O(1)操作执行:

今天服务器返回此信息。不幸的是,今天SDK没有公开这个属性。我们将在下次刷新SDK时修复此问题。在那之前你可以尝试这样做。

ResourceResponse<DocumentCollection> collectionReadResponse = await client.ReadDocumentCollectionAsync(…);
String quotaUsage = collectionReadResponse.ResponseHeaders["x-ms-resource-usage"];

// Quota Usage is a semicolon(;) delimited key-value pair. 
// The key "documentCount" will return the actual count of document.

这是标题的样子。

"functions=0;storedProcedures=0;triggers=0;documentSize=10178;documentsSize=5781669;documentsCount=17151514;collectionSize=10422760";

在此示例中,文档数量约为17M(17151514)。

答案 1 :(得分:1)

你走在正确的轨道上。只需要一些调整。您的麻烦似乎与您编写异步代码的方式有关。我花了一段时间才习惯为javascript编写异步代码。我相信你会得到它。以下是我注意到的事情:

  • 我的回调onReadDocuments()中没有任何内容会在返回1000文档页面后尝试进行其他查询。在onReadDocuments()内,您需要测试延续令牌是否为空并且接受仍然是真的。如果满足这两个条件,则应再次执行此语句accepted = collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);

  • 此外,在onReadDocuments()内部,此行可能没有达到预期的效果,responseOptions.continuation = responseOptionsContinuation;这里没有必要,因为您将其设置为高于此值并且它赢得了&#39; t被设置为新值,直到调用回调为止。

  • 您使用responseOptions作为onReadDocuments()的最后一个参数会让人感到困惑,因为它是请求回复标题而不是请求提交选项。将其更改为options

  • 您似乎有三种不同的方式来引用延续令牌,并且不会一直传递您设置的那个。建议,将参数从continuationToken更改为continuationTokenForThisSPROCExecution'. You already initialize it into the responseOptions so that's good, just update it to the new name. However, in onReadDocuments(), execute responseOptions.continuation = options.continuation;`

  • 为了确保你理解,sproc并在它超时之前调用许多1000个文档页面(根据我的经验,在卸载的系统上至少10,000个)。因此,您正在考虑上述更改,但如果sproc超时,您将需要稍微处理一下,这将涉及客户端的一些工作。您需要将最新的延续令牌传回主体和客户端,如果您看到带有延续令牌的响应,则需要再次调用该sproc(使用该延续令牌) 。然后,您需要将当前计数传递回sproc,以便继续添加,或者您需要在客户端累积它。

Here是CoffeeScript中完全成熟的示例(编译为JavaScript)。注意,如果使用documentdb-utils,它将继续调用sproc直到完成。否则,你自己需要这样做。