web-dev-qa-db-ja.com

存在しない可能性のあるAzureDocumentDBドキュメントを読み取る

次のように、AzureDocumentDBから単一のドキュメントをクエリできます。

var response = await client.ReadDocumentAsync( documentUri );

ドキュメントが存在しない場合、これはDocumentClientExceptionをスローします。私のプログラムでは、ドキュメントが存在する場合と存在しない場合があります。 try-catchを使用せずに、サーバーへの2回のラウンドトリップを行わずに、最初にドキュメントをクエリし、次にドキュメントが存在する場合はドキュメントを取得する方法はありますか?

15

特定のドキュメントを具体的にクエリしている場合、特定のドキュメントが見つからない場合(ステータスコードで404を返す)、ReadDocumentAsyncはそのDocumentClientExceptionをスローします。これは文書化されています ここ 。例外をキャッチすることで(そしてそれが404であることを確認することで)、2回の往復は必要ありません。

この例外に対処するには、CreateDocumentQuery()を使用して、個別の読み取りではなくクエリを作成する必要があります。次に、列挙できる結果セットを取得するだけです(その結果セットが空の場合でも)。例えば:

var collLink = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
var querySpec = new SqlQuerySpec { <querytext> };

var itr = client.CreateDocumentQuery(collLink, querySpec).AsDocumentQuery();
var response = await itr.ExecuteNextAsync<Document>();

foreach (var doc in response.AsEnumerable())
{
    // ...
}

このアプローチでは、応答がありません。 WHERE句を追加して特定のドキュメントをそのIDでクエリする特定のケースでは、結果がゼロまたは1つになります。

9
David Makogon

残念ながら、例外を処理するか、2回呼び出すか、2番目のパスを選択した場合、パフォーマンス主導でドキュメントの存在を確認する方法は他にありません。

_public bool ExistsDocument(string id)
{
    var client = new DocumentClient(DatabaseUri, DatabaseKey);
    var collectionUri = UriFactory.CreateDocumentCollectionUri("dbName", "collectioName");
    var query = client.CreateDocumentQuery<Microsoft.Azure.Documents.Document>(collectionUri, new FeedOptions() { MaxItemCount = 1 });
    return query.Where(x => x.Id == id).Select(x=>x.Id).AsEnumerable().Any(); //using Linq
}
_

クライアントはすべてのDBアクセスメソッド間で共有する必要がありますが、自動で十分な例を示すためにクライアントを作成しました。

new FeedOptions () {MaxItemCount = 1}は、クエリが1つの結果に対して最適化されることを確認します(実際にはそれ以上は必要ありません)。

Select(x=>x.Id)は、他のデータが返されないようにします。指定せずにドキュメントが存在する場合は、すべての情報をクエリして返します。

10
Matias Quaranta