2016-07-26 1 views
1

Следующий SP - это attumpt, чтобы подсчитать все документы в коллекции и, в общем, научиться обрабатывать полную коллекцию.Как считать все документы, azure DocumentDB

По какой-то причине следующий обратный SP

{ "графа": 0, "QueryCount": 0}

в то время как я ожидал бы, чтобы вернуть

{ «счет»: 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); 
    } 
} 
+0

Не уверен, что я понимаю вопрос, но вы можете выполнить точный пейджинг с ORDER BY и LIMIT в вашем SQL/Linq или вы можете сделать приблизительный пейджинг с помощью 'options = new FeedOptions {MaxItemCount = 10};'. Это помогает? –

+0

Пейджинг помогает, если я могу спросить следующую страницу, пока у меня не будет всех страниц. Иными словами, как бы вы запросили 20 000 документов? –

+0

Вы можете указать «получить столько, сколько сможете» с -1 для MaxItemCount. Я все еще не следую. Что ты пытаешься сделать? Какой код вы используете, чтобы попытаться это сделать? Какой результат/ответ вы ожидаете? и как это отличается от того, что вы на самом деле получаете? –

ответ

1

Вы на правильном пути. Просто нужно несколько настроек. Ваши проблемы, кажется, в том, как вы пишете асинхронный код. Мне потребовалось некоторое время, чтобы привыкнуть писать асинхронный код для javascript. Я уверен, что вы это получите. Вот то, что я замечаю:

  • Я не вижу ничего обратного вызова onReadDocuments(), что попытается сделать другой запрос после того, как он возвращается с страницы на 1000 документов. Внутри onReadDocuments() вам нужно проверить, что токен продолжения не равен NULL, и это принято по-прежнему. Если оба эти условия выполнены, то вы должны выполнить эту инструкцию еще раз, accepted = collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);

  • Кроме того, внутри onReadDocuments(), эта линия, вероятно, не делать то, что вы ожидаете, responseOptions.continuation = responseOptionsContinuation; Это ненужно здесь, потому что вы установите его выше, что и ему не будет установлено новое значение до тех пор, пока не будет вызван обратный вызов.

  • Ваше использование responseOptions в качестве последнего параметра вашего onReadDocuments() сбивает с толку, потому что это заголовки ответа на запрос, а не параметр отправки запроса. Измените это на options.

  • У вас, кажется, есть три разных способа обращения к токену продолжения и не последовательно проходить в том, который вы установили. Предложение, измените параметр на sproc от 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 до завершения. В противном случае вам нужно будет сделать это самостоятельно.

5

Обратите внимание, что общее количество документов теперь возвращается как заголовок DocumentDB. Вы можете выполнить это как операцию O (1), вызвав GET/colls/collectionName (ReadDocumentCollectionAsync в .NET):

Сервер сегодня возвращает эту информацию. К сожалению, сегодня 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).

+0

Благодарим вас за объяснение и дополнительную информацию. –

 Смежные вопросы

  • Нет связанных вопросов^_^