如何计算所有文档,azure DocumentDB

How to count all docs, azure DocumentDB

下一个SP是尝试对集合中的所有文档进行计数,并大致了解如何处理整个集合。

出于某种原因下一个 SP return

{"count":0,"QueryCount":0}

虽然我希望它 return

{"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);
    }
}

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

  • 我在您的回调 onReadDocuments() 中没有看到任何内容会尝试在 returns 之后使用 1000 个文档页面进行另一个查询。在 onReadDocuments() 内,您需要测试继续标记不为空并且接受的标记仍然为真。如果这两个条件都满足,那么你应该再次执行这条语句,accepted = collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);

  • 另外,在onReadDocuments()里面,这一行可能没有达到你的预期,responseOptions.continuation = responseOptionsContinuation;这里没有必要,因为你把它设置在上面,它不会在调用回调之前设置为新值。

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

  • 您似乎有三种不同的方式来引用延续标记,并且没有始终如一地传入您设置的方式。建议,把sproc的参数从continuationToken改成continuationTokenForThisSPROCExecution'. You already initialize it into theresponseOptionsso that's good, just update it to the new name. However, inonReadDocuments(), executeresponseOptions.continuation = options.continuation;`

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

Here 是 CoffeeScript 中一个完整的示例(编译为 JavaScript)。请注意,如果您使用 documentdb-utils,它将继续调用存储过程直到完成。否则,你需要自己做。

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

服务器今天returns这个信息。不幸的是,今天的 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.

这是 header 的样子。

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

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