기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
테이블 및 인덱스 스캔: .NET
Scan
작업은 Amazon DynamoDB에서 테이블 또는 인덱스의 모든 항목을 읽어옵니다.
다음은 AWS SDK for .NET 하위 수준 API를 사용하여 테이블을 스캔하는 단계입니다.
-
AmazonDynamoDBClient
클래스의 인스턴스를 만듭니다. -
ScanRequest
클래스 인스턴스를 생성하여 스캔 작업 파라미터를 입력합니다.이때는 테이블 이름 파라미터만 있으면 됩니다.
-
Scan
메서드를 실행하고 이전 단계에서 생성한ScanRequest
객체를 입력합니다.
다음은 포럼 스레드 댓글을 저장하는 Reply
테이블입니다.
예
>Reply ( <emphasis role="underline">Id</emphasis>, <emphasis role="underline">ReplyDateTime</emphasis>, Message, PostedBy )
이 테이블에는 다양한 포럼 스레드의 댓글이 모두 저장됩니다. 따라서 기본 키도 Id
(파티션 키)와 ReplyDateTime
(정렬 키), 두 가지로 구성됩니다. 다음은 테이블 전체를 스캔하는 C# 코드 예제입니다. ScanRequest
인스턴스는 스캔할 테이블 이름을 지정합니다.
예
AmazonDynamoDBClient client = new AmazonDynamoDBClient(); var request = new ScanRequest { TableName = "Reply", }; var response = client.Scan(request); var result = response.ScanResult; foreach (Dictionary<string, AttributeValue> item in response.ScanResult.Items) { // Process the result. PrintItem(item); }
옵션 파라미터 지정
Scan
메서드는 여러 가지 선택적 파라미터를 지원합니다. 예를 들어 옵션으로 스캔 필터를 사용하여 스캔 결과를 필터링할 수 있습니다. 스캔 필터를 사용할 때는 필터 조건과 평가할 조건의 속성 이름을 지정합니다. 자세한 내용은 스캔을 참조하세요.
다음 C# 코드는 ProductCatalog
테이블을 스캔하여 가격이 0보다 작은 항목을 찾습니다. 이 샘플에서 지정하는 옵션 파라미터는 다음과 같습니다.
-
가격이 0보다 작은 항목만 가져오는
FilterExpression
파라미터(오류 조건) -
쿼리 결과로 가져올 항목 속성을 지정하는
ProjectionExpression
파라미터
다음 C# 코드 예제에서는 ProductCatalog
테이블을 스캔하여 가격이 0보다 작은 모든 항목을 찾습니다.
예
var forumScanRequest = new ScanRequest { TableName = "ProductCatalog", // Optional parameters. ExpressionAttributeValues = new Dictionary<string,AttributeValue> { {":val", new AttributeValue { N = "0" }} }, FilterExpression = "Price < :val", ProjectionExpression = "Id" };
또한 선택에 따라 옵션인 Limit
파라미터를 추가하여 페이지 크기 또는 페이지당 항목 수를 제한할 수 있습니다. Scan
메서드를 실행할 때마다 지정된 수의 항목이 있는 결과 한 페이지를 가져옵니다. 다음 페이지를 가져오려면 이전 페이지의 마지막 항목의 기본 키 값을 제공하여 Scan
메서드가 다음 항목 집합을 반환할 수 있도록 Scan
메서드를 다시 실행합니다. ExclusiveStartKey
속성을 설정하여 요청 시 이 정보를 제공합니다. 이 속성의 초기 값은 null이 될 수 있습니다. 연이어 다음 페이지까지 가져오려면 이 속성 값을 이전 페이지에서 마지막 항목의 기본 키로 업데이트해야 합니다.
다음은 ProductCatalog
테이블 전체를 스캔하는 C# 코드 예제입니다. 요청에서 옵션으로 Limit
및 ExclusiveStartKey
파라미터를 지정합니다. do/while
루프는 LastEvaluatedKey
가 null 값을 반환할 때까지 계속해서 한 페이지를 스캔합니다.
예
Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new ScanRequest { TableName = "ProductCatalog", Limit = 10, ExclusiveStartKey = lastKeyEvaluated }; var response = client.Scan(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0);
예 - .NET을 사용한 스캔
다음 C# 코드는 ProductCatalog
테이블을 스캔하여 가격이 0보다 작은 항목을 찾는 작업 예제입니다.
다음 샘플을 테스트하기 위한 step-by-step 지침은 을 참조하십시오.NET 코드 예시.
using System; using System.Collections.Generic; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelScan { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { FindProductsForPriceLessThanZero(); Console.WriteLine("Example complete. To continue, press Enter"); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } } private static void FindProductsForPriceLessThanZero() { Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new ScanRequest { TableName = "ProductCatalog", Limit = 2, ExclusiveStartKey = lastKeyEvaluated, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":val", new AttributeValue { N = "0" }} }, FilterExpression = "Price < :val", ProjectionExpression = "Id, Title, Price" }; var response = client.Scan(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { Console.WriteLine("\nScanThreadTableUsePaging - printing....."); PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0); 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("************************************************"); } } }
예 - .NET을 사용한 병렬 스캔
다음은 병렬 스캔을 설명하는 C# 코드 예제입니다. 프로그램이 ProductCatalog
테이블을 삭제했다가 재생성한 후 테이블에 데이터를 로드합니다. 데이터 로드가 끝나면 프로그램이 다수의 스레드를 생성하여 병렬 Scan
요청을 실행합니다. 마지막으로 프로그램은 런타임 통계를 요약하여 출력합니다.
다음 샘플 테스트 step-by-step 지침은 을 참조하십시오.NET 코드 예시.
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelParallelScan { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); private static string tableName = "ProductCatalog"; private static int exampleItemCount = 100; private static int scanItemLimit = 10; private static int totalSegments = 5; static void Main(string[] args) { try { DeleteExampleTable(); CreateExampleTable(); UploadExampleData(); ParallelScanExampleTable(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void ParallelScanExampleTable() { Console.WriteLine("\n*** Creating {0} Parallel Scan Tasks to scan {1}", totalSegments, tableName); Task[] tasks = new Task[totalSegments]; for (int segment = 0; segment < totalSegments; segment++) { int tmpSegment = segment; Task task = Task.Factory.StartNew(() => { ScanSegment(totalSegments, tmpSegment); }); tasks[segment] = task; } Console.WriteLine("All scan tasks are created, waiting for them to complete."); Task.WaitAll(tasks); Console.WriteLine("All scan tasks are completed."); } private static void ScanSegment(int totalSegments, int segment) { Console.WriteLine("*** Starting to Scan Segment {0} of {1} out of {2} total segments ***", segment, tableName, totalSegments); Dictionary<string, AttributeValue> lastEvaluatedKey = null; int totalScannedItemCount = 0; int totalScanRequestCount = 0; do { var request = new ScanRequest { TableName = tableName, Limit = scanItemLimit, ExclusiveStartKey = lastEvaluatedKey, Segment = segment, TotalSegments = totalSegments }; var response = client.Scan(request); lastEvaluatedKey = response.LastEvaluatedKey; totalScanRequestCount++; totalScannedItemCount += response.ScannedCount; foreach (var item in response.Items) { Console.WriteLine("Segment: {0}, Scanned Item with Title: {1}", segment, item["Title"].S); } } while (lastEvaluatedKey.Count != 0); Console.WriteLine("*** Completed Scan Segment {0} of {1}. TotalScanRequestCount: {2}, TotalScannedItemCount: {3} ***", segment, tableName, totalScanRequestCount, totalScannedItemCount); } private static void UploadExampleData() { Console.WriteLine("\n*** Uploading {0} Example Items to {1} Table***", exampleItemCount, tableName); Console.Write("Uploading Items: "); for (int itemIndex = 0; itemIndex < exampleItemCount; itemIndex++) { Console.Write("{0}, ", itemIndex); CreateItem(itemIndex.ToString()); } Console.WriteLine(); } private static void CreateItem(string itemIndex) { var request = new PutItemRequest { TableName = tableName, Item = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = itemIndex }}, { "Title", new AttributeValue { S = "Book " + itemIndex + " Title" }}, { "ISBN", new AttributeValue { S = "11-11-11-11" }}, { "Authors", new AttributeValue { SS = new List<string>{"Author1", "Author2" } }}, { "Price", new AttributeValue { N = "20.00" }}, { "Dimensions", new AttributeValue { S = "8.5x11.0x.75" }}, { "InPublication", new AttributeValue { BOOL = false } } } }; client.PutItem(request); } private static void CreateExampleTable() { Console.WriteLine("\n*** Creating {0} Table ***", tableName); var request = new CreateTableRequest { AttributeDefinitions = new List<AttributeDefinition>() { new AttributeDefinition { AttributeName = "Id", AttributeType = "N" } }, KeySchema = new List<KeySchemaElement> { new KeySchemaElement { AttributeName = "Id", KeyType = "HASH" //Partition key } }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 5, WriteCapacityUnits = 6 }, TableName = tableName }; var response = client.CreateTable(request); var result = response; var tableDescription = result.TableDescription; Console.WriteLine("{1}: {0} \t ReadsPerSec: {2} \t WritesPerSec: {3}", tableDescription.TableStatus, tableDescription.TableName, tableDescription.ProvisionedThroughput.ReadCapacityUnits, tableDescription.ProvisionedThroughput.WriteCapacityUnits); string status = tableDescription.TableStatus; Console.WriteLine(tableName + " - " + status); WaitUntilTableReady(tableName); } private static void DeleteExampleTable() { try { Console.WriteLine("\n*** Deleting {0} Table ***", tableName); var request = new DeleteTableRequest { TableName = tableName }; var response = client.DeleteTable(request); var result = response; Console.WriteLine("{0} is being deleted...", tableName); WaitUntilTableDeleted(tableName); } catch (ResourceNotFoundException) { Console.WriteLine("{0} Table delete failed: Table does not exist", tableName); } } private static void WaitUntilTableReady(string tableName) { string status = null; // Let us wait until table is created. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. So we handle the potential exception. } } while (status != "ACTIVE"); } private static void WaitUntilTableDeleted(string tableName) { string status = null; // Let us wait until table is deleted. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { Console.WriteLine("Table name: {0} is not found. It is deleted", tableName); return; } } while (status == "DELETING"); } } }