2

ユーザーに関する情報を格納するために Azure DocumentDB を使用しています。これらのドキュメントには、 date_createdというプロパティが含まれています。このコレクション内に格納されているすべてのユーザーを取得するために、documentDB にクエリを送信したいと考えています。また、結果を新しいものから古いものの順に並べたいと思っています。

私は現在、コレクションを通過し、日付プロパティに基づいて結果を並べ替えるストアド プロシージャを DocumentDB に実装しています。ただし、2 つの質問があります。

  1. クエリに対して複数のドキュメントを返す場合、DocumentDB で使用される既定の順序は何ですか?
  2. DocumentDB では順序付け制御がまだサポートされていないことは理解していますが、ストア プロシージャを使用して結果を順序付けする場合、完全なコレクション スキャンを実行していますか、それともデータベースは少なくとも並べ替え対象のプロパティのインデックスを利用していますか? 参考までに、私が使用しているストア プロシージャは次のとおりです (製品チームによって提供された Azure サンプルからわずかに変更されています)。

    function orderBy(filterQuery, orderByFieldName, continuationToken) { 
    // HTTP error codes sent to our callback funciton by DocDB server. 
    var ErrorCode = { 
        REQUEST_ENTITY_TOO_LARGE: 413, 
    }
    var collection = getContext().getCollection(); 
    var collectionLink = collection.getSelfLink(); 
    var result = new Array(); 
    
    tryQuery({}); 
    
    function tryQuery(options) { 
        var isAccepted = (filterQuery && filterQuery.length) ? 
            collection.queryDocuments(collectionLink, filterQuery, options, callback) : 
            collection.readDocuments(collectionLink, options, callback) 
    
        if (!isAccepted) throw new Error("Source dataset is too large to complete the operation."); 
    } 
    
    /** 
    * queryDocuments callback. 
    * @param {Error} err - Error object in case of error/exception. 
    * @param {Array} queryFeed - array containing results of the query. 
    * @param {ResponseOptions} responseOptions. 
    */ 
    function callback(err, queryFeed, responseOptions) { 
        if (err) { 
            throw err; 
        } 
    
        // Iterate over document feed and store documents into the result array. 
        queryFeed.forEach(function (element, index, array) { 
            result[result.length] = element; 
        }); 
    
        if (responseOptions.continuation) { 
            // If there is continuation, call query again providing continuation token. 
            tryQuery({ continuation: responseOptions.continuation }); 
        } else { 
            // We are done with querying/got all results. Sort the results and return from the script. 
            result.sort(compare); 
    
            fillResponse(); 
        } 
    } 
    
    // Compare two objects(documents) using field specified by the orderByFieldName parameter. 
    // Return 0 if equal, -1 if less, 1 if greater. 
    function compare(x, y) { 
        if (x[orderByFieldName] == y[orderByFieldName]) return 0; 
        else if (x[orderByFieldName] < y[orderByFieldName]) return 1; 
        return -1; 
    } 
    
    // This is called in the very end on an already sorted array. 
    // Sort the results and set the response body. 
    function fillResponse() {
        var page_size = 20;
        // Main script is called with continuationToken which is the index of 1st item to start result batch from. 
        // Slice the result array and discard the beginning. From now on use the 'continuationResult' var. 
        var continuationResult = result; 
        if (continuationToken) continuationResult = result.slice(continuationToken); 
        else continuationToken = 0;
    
        if (page_size > continuationResult.length ) {
            page_size = continuationResult.length;
        }
    
        // Get/initialize the response. 
        var response = getContext().getResponse(); 
        response.setBody(null); 
    
        // Take care of response body getting too large: 
        // Set Response iterating by one element. When we fail due to MAX response size, return to the client requesting continuation. 
        var i = 0;
        var final_result = [];
        for (; i < page_size; ++i) { 
            try { 
                // Note: setBody is very expensive vs appendBody, use appendBody with simple approximation JSON.stringify(element).
                final_result.push(continuationResult[i]);                   
            } catch (ex) { 
                if (!ex.number == ErrorCode.REQUEST_ENTITY_TOO_LARGE) throw ex; 
                break; 
            } 
        } 
    
        /* Now next batch to return to client has i elements. 
        // Slice the continuationResult if needed and discard the end. */
        var partialResult = continuationResult; 
        var newContinuation = null; 
        if (i < continuationResult.length) { 
            partialResult = continuationResult.slice(0, i); 
        }
    
        // Finally, set response body.          
        response.setBody({ result: final_result, continuation: i }); 
    } 
    

    }

4

1 に答える 1

3

更新: 2015 年 7 月現在 - DocumentDB はクエリで ORDER BY をサポートしています

現時点では、クライアントまたはストアド プロシージャでコレクションを並べ替える必要があります (ただし、ストアド プロシージャは実行に制限があるため、クライアントでソートすることをお勧めします)。

質問に答えるには:

1) デフォルトの順序が保証されているとは思えない

2) ストアド プロシージャはコレクション スキャンを実行し、それを並べ替えます。

Azure フィードバック フォーラム ( http://feedback.azure.com/forums/263030-documentdb/suggestions/6334829--order-by-in-queries ) で意見を表明することで、"Order By" を推し進めることができます。

于 2014-11-22T08:00:22.470 に答える