2017-02-15 20 views
0

頭文件DB不提供對數()的支持,他們提供了一個stored procedure讓我在我的存儲過程使用了下面獲取用於計數不同的結果在documentdb

function usp_GetInfinityDataView(param) { 
    var context = getContext(); 
    var response = context.getResponse(); 
    var collection = context.getCollection(); 
    var collectionLink = collection.getSelfLink(); 
    var Rount = 0; 
    count("SELECT i.id FROM infinity i",null); 

    var query = { 
    query: 'SELECT * FROM infinity i' 
    }; 

    getNodes(param["ContinuationToken"],param["PageSize"]); 

    function getNodes(continuationToken,intPageSize) { 
    // Tune the pageSize to fit your dataset. 
    var requestOptions = { 
     continuation: continuationToken, 
     pageSize: intPageSize 
    }; 

    var accepted = collection.queryDocuments(collectionLink, query, requestOptions, 
     function(err, documentsRead, responseOptions) { 
     response.setBody({ 
       "ResponseContinuation": responseOptions.continuation, 
       "Count": Rount, 
       "ViewData": documentsRead 
      }); 
     }); 
    } 

    function count(filterQuery, continuationToken) { 
    var collection = getContext().getCollection(); 
    var maxResult = 99999999999; // MAX number of docs to process in one batch, when reached, return to client/request continuation. 
         // intentionally set low to demonstrate the concept. This can be much higher. Try experimenting. 
         // We've had it in to the high thousands before seeing the stored proceudre timing out. 

    // The number of documents counted. 
    var result = 0; 

    tryQuery(continuationToken); 

    // Helper method to check for max result and call query. 
    function tryQuery(nextContinuationToken) { 
     var responseOptions = { continuation: nextContinuationToken, pageSize : maxResult }; 

     // In case the server is running this script for long time/near timeout, it would return false, 
     // in this case we set the response to current continuation token, 
     // and the client will run this script again starting from this continuation. 
     // When the client calls this script 1st time, is passes empty continuation token. 
     if (result >= maxResult || !query(responseOptions)) { 
      setBody(nextContinuationToken); 
     } 
    } 

    function query(responseOptions) { 
     // For empty query string, use readDocuments rather than queryDocuments -- it's faster as doesn't need to process the query. 
     return (filterQuery && filterQuery.length) ? 
      collection.queryDocuments(collection.getSelfLink(), filterQuery, responseOptions, onReadDocuments) : 
      collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments); 
    } 

    // This is callback is called from collection.queryDocuments/readDocuments. 
    function onReadDocuments(err, docFeed, responseOptions) { 
     if (err) { 
      throw 'Error while reading document: ' + err; 
     } 

     // Increament the number of documents counted so far. 
     result += docFeed.length; 

     // If there is continuation, call query again with it, 
     // otherwise we are done, in which case set continuation to null. 
     if (responseOptions.continuation) { 
      tryQuery(responseOptions.continuation); 
     } else { 
      setBody(null); 
     } 
    } 

    // Set response body: use an object the client is expecting (2 properties: result and continuationToken). 
    function setBody(continuationToken) { 
     Rount = result; 
    } 
} 
} 

的問題是計數每次我從c#web api調用這個過程時,它給了我不同的結果,而不是實際的計數(就像我的結果集計數爲17491,但是返回17020或17202,有時也返回總計)。當結果數量少時,它可以正常工作即在另一個collection.I試圖分離兩個程序,但仍然是相同的。

回答

0

存儲過程在超過某個限制(至少時間)時被強制終止。這就是爲什麼您鏈接的原始示例返回正文中的延續標記的原因。您上面的版本已刪除,但您需要恢復它。這樣,如果從第一次調用存儲過程返回的結果包含連續標記,則需要再次調用它。最終計數將是對存儲過程的所有調用的總和。

您可能還想將maxResult降低迴1000或10,000。這給你提供了更精細的粒度,並且根據我的經驗,實際上得到的答案比擁有非常大的數字更快。

我不是示例計數存儲過程寫入方式的巨大粉絲。 Here是我的等價物。主要區別在於它返回的對象的形狀與其接受的形狀相同,並且每次重新啓動已終止的存儲過程所需的所有狀態都會前後傳遞。我已經寫過關於編寫存儲過程的方法here。 documentdb-utils(這些鏈接去的地方)包含Azure提供的node.js SDK的包裝器,它將自動保持調用過早終止的存儲過程直到它們實際完成。充分披露,我是documentdb-utils的作者。