テーブルおよびインデックスにクエリを実行: .NET - Amazon DynamoDB

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

テーブルおよびインデックスにクエリを実行: .NET

Query オペレーションを使用すると、Amazon DynamoDB でテーブルまたはセカンダリインデックスのクエリを実行できます。この関数ではパーティションキー値と等価条件を指定する必要があります。テーブルまたはインデックスにソートキーがある場合は、ソートキー値と条件を指定することで結果を絞り込むことができます。

以下は、低レベル AWS SDK for .NET API を使用してテーブルをクエリするステップです。

  1. AmazonDynamoDBClient クラスのインスタンスを作成します。

  2. QueryRequest クラスのインスタンスを作成して、クエリオペレーションパラメータを指定します。

  3. Query メソッドを実行し、前述のステップで作成した QueryRequest オブジェクトを指定します。

    応答には、クエリによって返されたすべての項目を示す QueryResult オブジェクトが含まれています。

以下の C# コード例は、前述のタスクの例です。このコードでは、フォーラムスレッドへの返信を格納する Reply テーブルがあることを前提としています。詳細については、「DynamoDB でのコード例用のテーブルの作成とデータのロード」を参照してください。

Reply Id, ReplyDateTime, ... )

各フォーラムスレッドには一意の ID があり、0 またはそれ以上の返信を受け取ることができます。したがってプライマリキーは、Id (パーティションキー) と ReplyDateTime (ソートキー) の両方で構成されます。

次のクエリでは、特定のスレッド件名に対するすべての返信を取り出します。このクエリでは、テーブル名と Subject の両方の値が必要になります。

AmazonDynamoDBClient client = new AmazonDynamoDBClient(); var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 1" }}} }; var response = client.Query(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { // Process the result. PrintItem(item); }

オプションパラメータの指定

Query メソッドでは、複数のオプションパラメータがサポートされています。たとえば、必要に応じて条件を指定して前述のクエリの結果を絞り込み、過去 2 週間の返信が返されるようにできます。この条件はソートキー条件と呼ばれます。指定したクエリ条件が DynamoDB によってプライマリキーのソートキーに対して評価されるためです。その他のオプションパラメータを指定して、クエリ結果の項目から特定の属性のリストだけを取り出すこともできます。詳細については、「クエリ」を参照してください。

次の C# コード例では、過去 15 日間に投稿されたフォーラムスレッドの返信が取り出されます。この例では、次のオプションパラメータが指定されています。

  • 過去 15 日間の返信だけを取り出す KeyConditionExpression

  • クエリ結果内の項目について取得する属性のリストを指定する ProjectionExpression パラメータ。

  • 強力な整合性のある読み込みを実行する ConsistentRead パラメータ。

DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id and ReplyDateTime > :v_twoWeeksAgo", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }}, {":v_twoWeeksAgo", new AttributeValue { S = twoWeeksAgoString }} }, ProjectionExpression = "Subject, ReplyDateTime, PostedBy", ConsistentRead = true }; var response = client.Query(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { // Process the result. PrintItem(item); }

また、オプションの Limit パラメータを追加することで、ページサイズ、またはページあたりの項目数を制限することもできます。Query メソッドを実行するたびに、指定された数の項目を含む結果が 1 ページ取得されます。次のページを取得するには、前ページの最後の項目のプライマリキーの値を入力して、Query メソッドを再度実行します。そうすることで、次の項目のセットを返すことができます。この情報は、ExclusiveStartKey プロパティを設定することでリクエストに含めます。このプロパティは最初は null である場合があります。以降のページを取り出すには、このプロパティ値を更新して、前ページの最後の項目のプライマリキーにする必要があります。

次の C# 例では、Reply テーブルのクエリを実行しています。リクエストでは、オプションの Limit および ExclusiveStartKey パラメータを指定しています。do/while ループは、LastEvaluatedKey から null 値が返されるまで、一度に 1 ページのスキャンを継続します。

Dictionary<string,AttributeValue> lastKeyEvaluated = null; do { var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }} }, // Optional parameters. Limit = 1, ExclusiveStartKey = lastKeyEvaluated }; var response = client.Query(request); // Process the query result. foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0);

例 - を使用したクエリ AWS SDK for .NET

以下のテーブルには、フォーラムのコレクションに関する情報が格納されています。詳細については、「DynamoDB でのコード例用のテーブルの作成とデータのロード」を参照してください。

Forum ( Name, ... ) Thread ( ForumName, Subject, Message, LastPostedBy, LastPostDateTime, ...) Reply ( Id, ReplyDateTime, Message, PostedBy, ...)

この例では、「DynamoDB」フォーラムの「DynamoDB Thread 1」スレッドに対するさまざまな返信の「検索」を実行します。

  • スレッドに対する返信を検索します。

  • スレッドに対する返信を検索します。Limit クエリパラメータを指定してページサイズを設定します。

    この関数は、複数のページの結果を処理するページ分割の使用を示しています。DynamoDB にはページサイズの制限があり、結果がページサイズを超えた場合には、結果の最初のページだけが得られます。このコーディングパターンによって、確実にクエリ結果の全ページがコードで処理されます。

  • 過去 15 日間の返信を検索します。

  • 特定の日付範囲の返信を検索します。

    前述の 2 つのクエリはどちらも、ソートキー条件を指定してクエリ結果を絞り込む方法、必要に応じてその他のクエリパラメータを使用する方法を示しています。

次の例をテストする step-by-step 手順については、「」を参照してください.NET コード例

using System; using System.Collections.Generic; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.Runtime; using Amazon.Util; namespace com.amazonaws.codesamples { class LowLevelQuery { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { // Query a specific forum and thread. string forumName = "Amazon DynamoDB"; string threadSubject = "DynamoDB Thread 1"; FindRepliesForAThread(forumName, threadSubject); FindRepliesForAThreadSpecifyOptionalLimit(forumName, threadSubject); FindRepliesInLast15DaysWithConfig(forumName, threadSubject); FindRepliesPostedWithinTimePeriod(forumName, threadSubject); Console.WriteLine("Example complete. To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); Console.ReadLine(); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); Console.ReadLine(); } } private static void FindRepliesPostedWithinTimePeriod(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesPostedWithinTimePeriod() ***"); string replyId = forumName + "#" + threadSubject; // You must provide date value based on your test data. DateTime startDate = DateTime.UtcNow - TimeSpan.FromDays(21); string start = startDate.ToString(AWSSDKUtils.ISO8601DateFormat); // You provide date value based on your test data. DateTime endDate = DateTime.UtcNow - TimeSpan.FromDays(5); string end = endDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId and ReplyDateTime between :v_start and :v_end", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }}, {":v_start", new AttributeValue { S = start }}, {":v_end", new AttributeValue { S = end }} } }; var response = client.Query(request); Console.WriteLine("\nNo. of reads used (by query in FindRepliesPostedWithinTimePeriod) {0}", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesInLast15DaysWithConfig(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesInLast15DaysWithConfig() ***"); string replyId = forumName + "#" + threadSubject; DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId and ReplyDateTime > :v_interval", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }}, {":v_interval", new AttributeValue { S = twoWeeksAgoString }} }, // Optional parameter. ProjectionExpression = "Id, ReplyDateTime, PostedBy", // Optional parameter. ConsistentRead = true }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesInLast15DaysWithConfig) {0}", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesForAThreadSpecifyOptionalLimit(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesForAThreadSpecifyOptionalLimit() ***"); string replyId = forumName + "#" + threadSubject; Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }} }, Limit = 2, // The Reply table has only a few sample items. So the page size is smaller. ExclusiveStartKey = lastKeyEvaluated }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesForAThreadSpecifyLimit) {0}\n", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesForAThread(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesForAThread() ***"); string replyId = forumName + "#" + threadSubject; var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }} } }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesForAThread) {0}\n", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void PrintItem( Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( attributeName + " " + (value.S == null ? "" : "S=[" + value.S + "]") + (value.N == null ? "" : "N=[" + value.N + "]") + (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]") ); } Console.WriteLine("************************************************"); } } }