DynamoDB - ดัชนีรองในเครื่อง
แอปพลิเคชันบางตัวดำเนินการสืบค้นด้วยคีย์หลักเท่านั้น แต่บางสถานการณ์จะได้รับประโยชน์จากคีย์การเรียงลำดับสำรอง อนุญาตให้แอปพลิเคชันของคุณเลือกโดยการสร้างดัชนีรองในเครื่องเดียวหรือหลายดัชนี
ข้อกำหนดในการเข้าถึงข้อมูลที่ซับซ้อนเช่นการรวมรายการหลายล้านรายการทำให้จำเป็นต้องดำเนินการสืบค้น / สแกนที่มีประสิทธิภาพมากขึ้น ดัชนีรองในเครื่องมีคีย์การเรียงลำดับสำรองสำหรับค่าคีย์พาร์ติชัน นอกจากนี้ยังมีสำเนาแอตทริบิวต์ของตารางทั้งหมดหรือบางส่วน พวกเขาจัดระเบียบข้อมูลด้วยคีย์พาร์ติชันตาราง แต่ใช้คีย์การจัดเรียงอื่น
การใช้ดัชนีทุติยภูมิในเครื่องจะช่วยขจัดความจำเป็นในการสแกนทั้งตารางและช่วยให้สามารถสืบค้นข้อมูลได้ง่ายและรวดเร็วโดยใช้คีย์การจัดเรียง
ดัชนีทุติยภูมิในพื้นที่ทั้งหมดต้องเป็นไปตามเงื่อนไขบางประการ -
- คีย์พาร์ติชันที่เหมือนกันและคีย์พาร์ติชันตารางต้นทาง
- คีย์การจัดเรียงของแอตทริบิวต์สเกลาร์เพียงรายการเดียว
- การฉายภาพของคีย์การจัดเรียงตารางต้นทางที่ทำหน้าที่เป็นแอตทริบิวต์ที่ไม่ใช่คีย์
ดัชนีรองในเครื่องทั้งหมดจะเก็บคีย์พาร์ติชันและเรียงลำดับจากตารางหลักโดยอัตโนมัติ ในแบบสอบถามหมายถึงการรวบรวมแอตทริบิวต์ที่คาดการณ์ไว้อย่างมีประสิทธิภาพและการดึงข้อมูลแอตทริบิวต์ที่ไม่ได้คาดการณ์ไว้ด้วย
ขีด จำกัด การจัดเก็บสำหรับดัชนีรองภายในเครื่องจะยังคงอยู่ที่ 10GB ต่อค่าคีย์พาร์ติชันซึ่งรวมถึงรายการตารางทั้งหมดและรายการดัชนีที่แชร์ค่าคีย์พาร์ติชัน
การฉายแอททริบิวต์
การดำเนินการบางอย่างต้องการการอ่าน / ดึงข้อมูลส่วนเกินเนื่องจากความซับซ้อน การดำเนินการเหล่านี้สามารถใช้ปริมาณงานได้มาก การฉายภาพช่วยให้คุณหลีกเลี่ยงการดึงข้อมูลที่มีราคาแพงและดำเนินการสืบค้นข้อมูลที่หลากหลายโดยการแยกแอตทริบิวต์เหล่านี้ โปรดจำไว้ว่าการคาดการณ์ประกอบด้วยแอตทริบิวต์ที่คัดลอกไปยังดัชนีรอง
เมื่อสร้างดัชนีรองคุณต้องระบุแอตทริบิวต์ที่คาดการณ์ไว้ เรียกคืนตัวเลือกสามตัวที่มีให้โดย DynamoDB:KEYS_ONLY, INCLUDE, and ALL.
เมื่อเลือกแอตทริบิวต์บางอย่างในการประมาณการให้พิจารณาการแลกเปลี่ยนต้นทุนที่เกี่ยวข้อง -
หากคุณคาดการณ์แอตทริบิวต์ที่จำเป็นเพียงเล็กน้อยคุณจะลดต้นทุนการจัดเก็บได้อย่างมาก
หากคุณคาดการณ์แอตทริบิวต์ที่ไม่ใช่คีย์ที่เข้าถึงบ่อยคุณจะชดเชยต้นทุนการสแกนด้วยต้นทุนการจัดเก็บ
หากคุณฉายแอตทริบิวต์ที่ไม่ใช่คีย์ส่วนใหญ่หรือทั้งหมดสิ่งนี้จะเพิ่มความยืดหยุ่นสูงสุดและลดปริมาณงาน (ไม่มีการดึงข้อมูล) อย่างไรก็ตามต้นทุนการจัดเก็บเพิ่มขึ้น
หากคุณคาดการณ์ KEYS_ONLY สำหรับการเขียน / อัปเดตบ่อยครั้งและการสืบค้นที่ไม่บ่อยนักระบบจะย่อขนาดให้เล็กที่สุด แต่ยังคงเตรียมการสืบค้นไว้
การสร้างดัชนีทุติยภูมิในท้องถิ่น
ใช้ LocalSecondaryIndexพารามิเตอร์ของ CreateTable เพื่อสร้างดัชนีรองภายในเครื่องเดียวหรือหลายตัว คุณต้องระบุแอตทริบิวต์ที่ไม่ใช่คีย์หนึ่งรายการสำหรับคีย์การเรียงลำดับ ในการสร้างตารางคุณจะสร้างดัชนีรองในเครื่อง ในการลบคุณจะลบดัชนีเหล่านี้
ตารางที่มีดัชนีรองภายในต้องเป็นไปตามขีด จำกัด ของขนาด 10GB ต่อค่าคีย์พาร์ติชัน แต่สามารถจัดเก็บรายการจำนวนเท่าใดก็ได้
การสืบค้นและการสแกนดัชนีทุติยภูมิในพื้นที่
การดำเนินการเคียวรีบนดัชนีรองภายในจะส่งคืนรายการทั้งหมดที่มีค่าคีย์พาร์ติชันที่ตรงกันเมื่อหลายรายการในดัชนีแบ่งค่าคีย์การเรียงลำดับ รายการที่ตรงกันจะไม่ส่งคืนตามลำดับที่แน่นอน การค้นหาสำหรับดัชนีทุติยภูมิภายในใช้ความสอดคล้องกันในท้ายที่สุดหรืออย่างใดอย่างหนึ่งโดยการอ่านที่สอดคล้องกันอย่างมากจะแสดงค่าล่าสุด
การสแกนจะส่งคืนข้อมูลดัชนีทุติยภูมิในเครื่องทั้งหมด การสแกนกำหนดให้คุณต้องระบุชื่อตารางและดัชนีและอนุญาตให้ใช้นิพจน์ตัวกรองเพื่อทิ้งข้อมูล
การเขียนรายการ
ในการสร้างดัชนีรองในเครื่องคุณต้องระบุแอตทริบิวต์คีย์การเรียงลำดับและประเภทข้อมูล เมื่อคุณเขียนรายการประเภทของรายการจะต้องตรงกับประเภทข้อมูลของคีย์สคีมาหากรายการนั้นกำหนดแอตทริบิวต์ของคีย์ดัชนี
DynamoDB ไม่กำหนดข้อกำหนดความสัมพันธ์แบบหนึ่งต่อหนึ่งบนรายการตารางและรายการดัชนีรองในเครื่อง ตารางที่มีดัชนีทุติยภูมิในเครื่องหลายตัวมีต้นทุนการเขียนสูงกว่าตารางที่มีค่าน้อย
การพิจารณาปริมาณงานในดัชนีทุติยภูมิในท้องถิ่น
การใช้ความจุในการอ่านของแบบสอบถามขึ้นอยู่กับลักษณะของการเข้าถึงข้อมูล ข้อความค้นหาใช้ความสอดคล้องในท้ายที่สุดหรืออย่างใดอย่างหนึ่งโดยมีการอ่านที่สอดคล้องกันอย่างมากโดยใช้หน่วยเดียวเทียบกับครึ่งหน่วยในการอ่านที่สอดคล้องกันในที่สุด
ข้อ จำกัด ของผลลัพธ์รวมถึงขนาดสูงสุด 1MB ขนาดผลลัพธ์มาจากผลรวมของขนาดรายการดัชนีที่ตรงกันปัดเศษขึ้นเป็น 4KB ที่ใกล้ที่สุดและขนาดรายการตารางที่ตรงกันจะปัดเศษเป็น 4KB ที่ใกล้ที่สุด
ปริมาณการใช้ความจุในการเขียนยังคงอยู่ในหน่วยที่จัดเตรียมไว้ คำนวณต้นทุนทั้งหมดที่จัดเตรียมโดยการหาผลรวมของหน่วยบริโภคในการเขียนตารางและหน่วยบริโภคในการอัปเดตดัชนี
คุณยังสามารถพิจารณาปัจจัยสำคัญที่มีผลต่อต้นทุนซึ่งบางส่วน ได้แก่ -
เมื่อคุณเขียนรายการที่กำหนดแอตทริบิวต์ที่จัดทำดัชนีหรืออัปเดตรายการเพื่อกำหนดแอตทริบิวต์ที่จัดทำดัชนีที่ไม่ได้กำหนดการดำเนินการเขียนครั้งเดียวจะเกิดขึ้น
เมื่อการอัปเดตตารางเปลี่ยนค่าแอตทริบิวต์ของคีย์ที่จัดทำดัชนีการเขียนสองครั้งจะเกิดขึ้นเพื่อลบแล้วเพิ่มรายการ
เมื่อการเขียนทำให้เกิดการลบแอตทริบิวต์ที่จัดทำดัชนีการเขียนหนึ่งรายการจะเกิดขึ้นเพื่อลบการคาดการณ์รายการเก่า
เมื่อไม่มีรายการอยู่ในดัชนีก่อนหรือหลังการอัพเดตจะไม่มีการเขียนใด ๆ เกิดขึ้น
การจัดเก็บดัชนีทุติยภูมิในเครื่อง
ในการเขียนรายการตาราง DynamoDB จะคัดลอกแอตทริบิวต์ที่เหมาะสมโดยอัตโนมัติไปยังดัชนีรองในเครื่องที่ต้องการ สิ่งนี้เรียกเก็บเงินจากบัญชีของคุณ ช่องว่างที่ใช้เป็นผลมาจากผลรวมของขนาดไบต์ของคีย์หลักของตารางขนาดไบต์แอ็ตทริบิวต์คีย์ดัชนีขนาดไบต์ของแอ็ตทริบิวต์ที่คาดการณ์ไว้ในปัจจุบันและ 100 ไบต์ในค่าโสหุ้ยสำหรับแต่ละรายการดัชนี
การจัดเก็บโดยประมาณได้มาจากการประมาณขนาดรายการดัชนีเฉลี่ยและคูณด้วยปริมาณรายการในตาราง
การใช้ Java เพื่อทำงานกับ Local Secondary Indexes
สร้างดัชนีรองในเครื่องโดยสร้างอินสแตนซ์คลาส DynamoDB ก่อน จากนั้นสร้างอินสแตนซ์คลาส CreateTableRequest พร้อมข้อมูลการร้องขอที่จำเป็น สุดท้ายใช้เมธอด createTable
ตัวอย่าง
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(
new ProfileCredentialsProvider()));
String tableName = "Tools";
CreateTableRequest createTableRequest = new
CreateTableRequest().withTableName(tableName);
//Provisioned Throughput
createTableRequest.setProvisionedThroughput (
new ProvisionedThroughput()
.withReadCapacityUnits((long)5)
.withWriteCapacityUnits(( long)5));
//Attributes
ArrayList<AttributeDefinition> attributeDefinitions =
new ArrayList<AttributeDefinition>();
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("Make")
.withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("Model")
.withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("Line")
.withAttributeType("S"));
createTableRequest.setAttributeDefinitions(attributeDefinitions);
//Key Schema
ArrayList<KeySchemaElement> tableKeySchema = new
ArrayList<KeySchemaElement>();
tableKeySchema.add(new KeySchemaElement()
.withAttributeName("Make")
.withKeyType(KeyType.HASH)); //Partition key
tableKeySchema.add(new KeySchemaElement()
.withAttributeName("Model")
.withKeyType(KeyType.RANGE)); //Sort key
createTableRequest.setKeySchema(tableKeySchema);
ArrayList<KeySchemaElement> indexKeySchema = new
ArrayList<KeySchemaElement>();
indexKeySchema.add(new KeySchemaElement()
.withAttributeName("Make")
.withKeyType(KeyType.HASH)); //Partition key
indexKeySchema.add(new KeySchemaElement()
.withAttributeName("Line")
.withKeyType(KeyType.RANGE)); //Sort key
Projection projection = new Projection()
.withProjectionType(ProjectionType.INCLUDE);
ArrayList<String> nonKeyAttributes = new ArrayList<String>();
nonKeyAttributes.add("Type");
nonKeyAttributes.add("Year");
projection.setNonKeyAttributes(nonKeyAttributes);
LocalSecondaryIndex localSecondaryIndex = new LocalSecondaryIndex()
.withIndexName("ModelIndex")
.withKeySchema(indexKeySchema)
.withProjection(p rojection);
ArrayList<LocalSecondaryIndex> localSecondaryIndexes = new
ArrayList<LocalSecondaryIndex>();
localSecondaryIndexes.add(localSecondaryIndex);
createTableRequest.setLocalSecondaryIndexes(localSecondaryIndexes);
Table table = dynamoDB.createTable(createTableRequest);
System.out.println(table.getDescription());
ดึงข้อมูลเกี่ยวกับดัชนีทุติยภูมิภายในด้วยวิธีการอธิบาย เพียงสร้างอินสแตนซ์คลาส DynamoDB สร้างอินสแตนซ์คลาส Table และส่งตารางไปยังเมธอดอธิบาย
ตัวอย่าง
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(
new ProfileCredentialsProvider()));
String tableName = "Tools";
Table table = dynamoDB.getTable(tableName);
TableDescription tableDescription = table.describe();
List<LocalSecondaryIndexDescription> localSecondaryIndexes =
tableDescription.getLocalSecondaryIndexes();
Iterator<LocalSecondaryIndexDescription> lsiIter =
localSecondaryIndexes.iterator();
while (lsiIter.hasNext()) {
LocalSecondaryIndexDescription lsiDescription = lsiIter.next();
System.out.println("Index info " + lsiDescription.getIndexName() + ":");
Iterator<KeySchemaElement> kseIter = lsiDescription.getKeySchema().iterator();
while (kseIter.hasNext()) {
KeySchemaElement kse = kseIter.next();
System.out.printf("\t%s: %s\n", kse.getAttributeName(), kse.getKeyType());
}
Projection projection = lsiDescription.getProjection();
System.out.println("\tProjection type: " + projection.getProjectionType());
if (projection.getProjectionType().toString().equals("INCLUDE")) {
System.out.println("\t\tNon-key projected attributes: " +
projection.getNonKeyAttributes());
}
}
ดำเนินการสืบค้นโดยใช้ขั้นตอนเดียวกับแบบสอบถามตาราง เพียงสร้างอินสแตนซ์คลาส DynamoDB อินสแตนซ์คลาสตารางอินสแตนซ์คลาสดัชนีวัตถุเคียวรีและใช้วิธีเคียวรี
ตัวอย่าง
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(
new ProfileCredentialsProvider()));
String tableName = "Tools";
Table table = dynamoDB.getTable(tableName);
Index index = table.getIndex("LineIndex");
QuerySpec spec = new QuerySpec()
.withKeyConditionExpression("Make = :v_make and Line = :v_line")
.withValueMap(new ValueMap()
.withString(":v_make", "Depault")
.withString(":v_line", "SuperSawz"));
ItemCollection<QueryOutcome> items = index.query(spec);
Iterator<Item> itemsIter = items.iterator();
while (itemsIter.hasNext()) {
Item item = itemsIter.next();
System.out.println(item.toJSONPretty());
}
คุณยังสามารถตรวจสอบตัวอย่างต่อไปนี้
Note- ตัวอย่างต่อไปนี้อาจถือว่าเป็นแหล่งข้อมูลที่สร้างขึ้นก่อนหน้านี้ ก่อนที่จะพยายามดำเนินการให้จัดหาไลบรารีที่สนับสนุนและสร้างแหล่งข้อมูลที่จำเป็น (ตารางที่มีคุณสมบัติที่ต้องการหรือแหล่งอ้างอิงอื่น ๆ )
ตัวอย่างต่อไปนี้ยังใช้ Eclipse IDE, ไฟล์หนังสือรับรอง AWS และ AWS Toolkit ภายใน Eclipse AWS Java Project
ตัวอย่าง
import java.util.ArrayList;
import java.util.Iterator;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Index;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.ItemCollection;
import com.amazonaws.services.dynamodbv2.document.PutItemOutcome;
import com.amazonaws.services.dynamodbv2.document.QueryOutcome;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.Projection;
import com.amazonaws.services.dynamodbv2.model.ProjectionType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ReturnConsumedCapacity;
import com.amazonaws.services.dynamodbv2.model.Select;
public class LocalSecondaryIndexSample {
static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(
new ProfileCredentialsProvider()));
public static String tableName = "ProductOrders";
public static void main(String[] args) throws Exception {
createTable();
query(null);
query("IsOpenIndex");
query("OrderCreationDateIndex");
}
public static void createTable() {
CreateTableRequest createTableRequest = new CreateTableRequest()
.withTableName(tableName)
.withProvisionedThroughput(new ProvisionedThroughput()
.withReadCapacityUnits((long) 1)
.withWriteCapacityUnits((long) 1));
// Table partition and sort keys attributes
ArrayList<AttributeDefinition> attributeDefinitions = new
ArrayList<AttributeDefinition>();
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("CustomerID")
.withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("OrderID")
.withAttributeType("N"));
// Index primary key attributes
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("OrderDate")
.withAttributeType("N"));
attributeDefinitions.add(new AttributeDefinition()
.withAttributeName("OpenStatus")
.withAttributeType("N"));
createTableRequest.setAttributeDefinitions(attributeDefinitions);
// Table key schema
ArrayList<KeySchemaElement> tableKeySchema = new
ArrayList<KeySchemaElement>();
tableKeySchema.add(new KeySchemaElement()
.withAttributeName("CustomerID")
.withKeyType(KeyType.HASH)); //Partition key
tableKeySchema.add(new KeySchemaElement()
.withAttributeName("OrderID")
.withKeyType(KeyType.RANGE)); //Sort key
createTableRequest.setKeySchema(tableKeySchema);
ArrayList<LocalSecondaryIndex> localSecondaryIndexes = new
ArrayList<LocalSecondaryIndex>();
// OrderDateIndex
LocalSecondaryIndex orderDateIndex = new LocalSecondaryIndex()
.withIndexName("OrderDateIndex");
// OrderDateIndex key schema
ArrayList<KeySchemaElement> indexKeySchema = new
ArrayList<KeySchemaElement>();
indexKeySchema.add(new KeySchemaElement()
.withAttributeName("CustomerID")
.withKeyType(KeyType.HASH)); //Partition key
indexKeySchema.add(new KeySchemaElement()
.withAttributeName("OrderDate")
.withKeyType(KeyType.RANGE)); //Sort key
orderDateIndex.setKeySchema(indexKeySchema);
// OrderCreationDateIndex projection w/attributes list
Projection projection = new Projection()
.withProjectionType(ProjectionType.INCLUDE);
ArrayList<String> nonKeyAttributes = new ArrayList<String>();
nonKeyAttributes.add("ProdCat");
nonKeyAttributes.add("ProdNomenclature");
projection.setNonKeyAttributes(nonKeyAttributes);
orderCreationDateIndex.setProjection(projection);
localSecondaryIndexes.add(orderDateIndex);
// IsOpenIndex
LocalSecondaryIndex isOpenIndex = new LocalSecondaryIndex()
.withIndexName("IsOpenIndex");
// OpenStatusIndex key schema
indexKeySchema = new ArrayList<KeySchemaElement>();
indexKeySchema.add(new KeySchemaElement()
.withAttributeName("CustomerID")
.withKeyType(KeyType.HASH)); //Partition key
indexKeySchema.add(new KeySchemaElement()
.withAttributeName("OpenStatus")
.withKeyType(KeyType.RANGE)); //Sort key
// OpenStatusIndex projection
projection = new Projection() .withProjectionType(ProjectionType.ALL);
OpenStatusIndex.setKeySchema(indexKeySchema);
OpenStatusIndex.setProjection(projection);
localSecondaryIndexes.add(OpenStatusIndex);
// Put definitions in CreateTable request
createTableRequest.setLocalSecondaryIndexes(localSecondaryIndexes);
System.out.println("Spawning table " + tableName + "...");
System.out.println(dynamoDB.createTable(createTableRequest));
// Pause for ACTIVE status
System.out.println("Waiting for ACTIVE table:" + tableName);
try {
Table table = dynamoDB.getTable(tableName);
table.waitForActive();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void query(String indexName) {
Table table = dynamoDB.getTable(tableName);
System.out.println("\n*************************************************\n");
System.out.println("Executing query on" + tableName);
QuerySpec querySpec = new QuerySpec()
.withConsistentRead(true)
.withScanIndexForward(true)
.withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL);
if (indexName == "OpenStatusIndex") {
System.out.println("\nEmploying index: '" + indexName
+ "' open orders for this customer.");
System.out.println(
"Returns only user-specified attribute list\n");
Index index = table.getIndex(indexName);
querySpec.withKeyConditionExpression("CustomerID = :v_custmid and
OpenStatus = :v_openstat")
.withValueMap(new ValueMap()
.withString(":v_custmid", "[email protected]")
.withNumber(":v_openstat", 1));
querySpec.withProjectionExpression(
"OrderDate, ProdCat, ProdNomenclature, OrderStatus");
ItemCollection<QueryOutcome> items = index.query(querySpec);
Iterator<Item> iterator = items.iterator();
System.out.println("Printing query results...");
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
} else if (indexName == "OrderDateIndex") {
System.out.println("\nUsing index: '" + indexName
+ "': this customer's orders placed after 05/22/2016.");
System.out.println("Projected attributes are returned\n");
Index index = table.getIndex(indexName);
querySpec.withKeyConditionExpression("CustomerID = :v_custmid and OrderDate
>= :v_ordrdate")
.withValueMap(new ValueMap()
.withString(":v_custmid", "[email protected]")
.withNumber(":v_ordrdate", 20160522));
querySpec.withSelect(Select.ALL_PROJECTED_ATTRIBUTES);
ItemCollection<QueryOutcome> items = index.query(querySpec);
Iterator<Item> iterator = items.iterator();
System.out.println("Printing query results...");
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
} else {
System.out.println("\nNo index: All Jane's orders by OrderID:\n");
querySpec.withKeyConditionExpression("CustomerID = :v_custmid")
.withValueMap(new ValueMap()
.withString(":v_custmid", "[email protected]"));
ItemCollection<QueryOutcome> items = table.query(querySpec);
Iterator<Item> iterator = items.iterator();
System.out.println("Printing query results...");
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
}
}
}