通过.NET确定每个查询的DocumentDB请求费用

时间:2014-11-09 19:58:26

标签: c# azure azure-cosmosdb

我试图弄清楚在通过提供的.NET客户端库执行DocumentDB查询请求时是否可以获得“请求费用”。详细信息返回底层的HTTP标题“x-ms-request-charge”,我可以通过Fiddler等进行监控,但如果我可以直接通过.NET获取它,我会更喜欢。

有人这样做过吗?或者至少能够确认是否根本不可能?

更新

补充说明我在执行查询而不是其他操作时需要收取费用。

2 个答案:

答案 0 :(得分:12)

你应该可以通过.Net库获得它。例如,请查看下面的屏幕截图,其中显示了Create New User操作的响应。结果是Microsoft.Azure.Client.ResourceResponse<T>类型,其中包含一个名为RequestCharge的属性。

enter image description here

<强>更新

所以我检查了查询结果,你是正确的,这不是直接在.Net库中公开的。但是,这可以在ResponseHeaders属性中找到,您可以使用以下内容找到它:

FeedResponse<Microsoft.Azure.Documents.Document> queryResult = await documentClient.CreateDocumentQuery<Microsoft.Azure.Documents.Document>(collectio‌​nSelfLink, query, options).AsDocumentQuery().ExecuteNextAsync<Microsoft.Azure.Documents.Document>(‌​);
var requestCharge = queryResult.ResponseHeaders["x-ms-request-charge"];

而不是在Fiddler中检查它。

注意

ExecuteNextAsync可能会返回带有延续令牌的结果子集。如果你想要所有的结果,你必须迭代直到文档db不发送abck一个延续令牌。

var docDbQueryable = documentClient.CreateDocumentQuery<Document>(collectio‌​nSelfLink, query, options).AsDocumentQuery();
var docDbResults = new List<Document>();
do
{
    var batchResult = await docDbQueryable.ExecuteNextAsync<Document>(‌​);;
    docDbResults.AddRange(batchResult);
}
while (docDbQueryable.HasMoreResults);
return docDbResults;

答案 1 :(得分:7)

您需要记录每个查询的成本并处理分页:

public async Task<IEnumerable<T>> Query<T>(string databaseId, string collectionId, SqlQuerySpec sqlQuery, int take)
where T : Resource
{
    double queryCost = 0;
    const int maxPageSize = 100;

    var query = _client.CreateDocumentQuery<T>(
        UriFactory.CreateDocumentCollectionUri(databaseId, collectionId),
        sqlQuery,
        new FeedOptions() {MaxItemCount = Math.Min(maxPageSize, take)}).AsDocumentQuery();

    var response = await query.ExecuteNextAsync<T>();
    queryCost += response.RequestCharge;
    var entities = response.ToList();

    while (entities.Count < take && query.HasMoreResults)
    {
        var nextResponse = await query.ExecuteNextAsync<T>();
        queryCost += nextResponse.RequestCharge;
        entities.AddRange(nextResponse);
    }

    Debug.WriteLine(
        "Query [{0}] for {1} documents in collection [{2}] cost {3} RUs.",
        sqlQuery.QueryText,
        take,
        collectionId,
        queryCost);

    return entities.Take(take).ToList(); // We may end up with more than the requested number of items.
}