我正在使用 Azure DocumentDB 来存储有关用户的信息。这些文档包含一个名为date_created的属性。我想向 documentDB 发送查询以检索存储在该集合中的所有用户。我还希望结果按从最新到最旧的顺序排列。
我目前在 DocumentDB 中实现了一个存储过程,它遍历集合并根据日期属性对结果进行排序。不过,我有两个问题:
- 当查询返回多个文档时,DocumentDB 使用的默认顺序是什么?
我知道 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 }); }
}
最佳答案
更新:截至 2015 年 7 月 - DocumentDB 在查询中支持 ORDER BY
目前,您需要在客户端或存储过程上对集合进行排序(尽管我建议在客户端上这样做,因为存储过程的执行是有限的)。
回答您的问题:
1) 我不相信有保证的默认排序
2) 存储过程将导致集合扫描,然后对其进行排序。
您可以通过在 Azure 反馈论坛上发表意见来帮助插入“排序依据”: http://feedback.azure.com/forums/263030-documentdb/suggestions/6334829--order-by-in-queries
关于azure - DocumentDB - 查询结果顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27040843/