

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menggunakan Indeks Sekunder Global: Java
<a name="GSIJavaDocumentAPI"></a>

Anda dapat menggunakan AWS SDK untuk Java Document API untuk membuat tabel Amazon DynamoDB dengan satu atau beberapa indeks sekunder global, menjelaskan indeks pada tabel, dan melakukan kueri menggunakan indeks. 

Berikut ini adalah langkah-langkah umum untuk operasi tabel. 

1. Buat instans dari kelas `DynamoDB`.

1. Berikan parameter wajib dan opsional untuk operasi dengan membuat objek permintaan yang sesuai. 

1. Panggil metode sesuai yang ditentukan oleh klien yang Anda buat pada langkah sebelumnya. 

**Topics**
+ [Membuat tabel dengan Indeks Sekunder Global](#GSIJavaDocumentAPI.CreateTableWithIndex)
+ [Mendeskripsikan tabel dengan Indeks Sekunder Global](#GSIJavaDocumentAPI.DescribeTableWithIndex)
+ [Mengkueri Indeks Sekunder Global](#GSIJavaDocumentAPI.QueryAnIndex)
+ [Contoh: Indeks Sekunder Global menggunakan API AWS SDK untuk Java dokumen](GSIJavaDocumentAPI.Example.md)

## Membuat tabel dengan Indeks Sekunder Global
<a name="GSIJavaDocumentAPI.CreateTableWithIndex"></a>

Anda dapat membuat indeks sekunder global pada saat membuat tabel. Untuk melakukannya, gunakan `CreateTable` dan berikan spesifikasi Anda untuk satu atau beberapa indeks sekunder global. Contoh kode Java berikut membuat tabel untuk menyimpan informasi tentang data cuaca. Kunci partisinya adalah `Location` dan kunci urutannya adalah `Date`. Indeks sekunder global bernama `PrecipIndex` memungkinkan akses cepat ke data curah hujan untuk berbagai lokasi.

Berikut adalah langkah-langkah untuk membuat tabel dengan indeks sekunder global, menggunakan API dokumen DynamoDB. 

1. Buat instans dari kelas `DynamoDB`.

1. Buat instans dari kelas `CreateTableRequest` untuk memberikan informasi permintaan.

   Anda harus memberikan nama tabel, kunci primernya, dan nilai throughput yang ditentukan. Untuk indeks sekunder global, Anda harus memberikan nama indeks, pengaturan throughput yang ditentukan, definisi atribut untuk kunci urutan indeks, skema kunci untuk indeks, dan proyeksi atribut.

1. Panggil metode `createTable` dengan menentukan objek permintaan sebagai parameter.

Contoh kode Java berikut mendemonstrasikan langkah sebelumnya. Kode tersebut membuat tabel (`WeatherData`) dengan indeks sekunder global (`PrecipIndex`). Kunci partisi indeksnya adalah `Date` dan kunci urutannya adalah `Precipitation`. Semua atribut tabel diproyeksikan ke dalam indeks. Pengguna dapat mengkueri indeks ini untuk mendapatkan data cuaca untuk tanggal tertentu, yang secara opsional mengurutkan data berdasarkan jumlah curah hujan. 

Karena `Precipitation` bukan atribut kunci untuk tabel tersebut, maka tidak diperlukan. Namun, item `WeatherData` tanpa `Precipitation` tidak muncul di `PrecipIndex`.

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

// Attribute definitions
ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();

attributeDefinitions.add(new AttributeDefinition()
    .withAttributeName("Location")
    .withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition()
    .withAttributeName("Date")
    .withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition()
    .withAttributeName("Precipitation")
    .withAttributeType("N"));

// Table key schema
ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>();
tableKeySchema.add(new KeySchemaElement()
    .withAttributeName("Location")
    .withKeyType(KeyType.HASH));  //Partition key
tableKeySchema.add(new KeySchemaElement()
    .withAttributeName("Date")
    .withKeyType(KeyType.RANGE));  //Sort key

// PrecipIndex
GlobalSecondaryIndex precipIndex = new GlobalSecondaryIndex()
    .withIndexName("PrecipIndex")
    .withProvisionedThroughput(new ProvisionedThroughput()
        .withReadCapacityUnits((long) 10)
        .withWriteCapacityUnits((long) 1))
        .withProjection(new Projection().withProjectionType(ProjectionType.ALL));

ArrayList<KeySchemaElement> indexKeySchema = new ArrayList<KeySchemaElement>();

indexKeySchema.add(new KeySchemaElement()
    .withAttributeName("Date")
    .withKeyType(KeyType.HASH));  //Partition key
indexKeySchema.add(new KeySchemaElement()
    .withAttributeName("Precipitation")
    .withKeyType(KeyType.RANGE));  //Sort key

precipIndex.setKeySchema(indexKeySchema);

CreateTableRequest createTableRequest = new CreateTableRequest()
    .withTableName("WeatherData")
    .withProvisionedThroughput(new ProvisionedThroughput()
        .withReadCapacityUnits((long) 5)
        .withWriteCapacityUnits((long) 1))
    .withAttributeDefinitions(attributeDefinitions)
    .withKeySchema(tableKeySchema)
    .withGlobalSecondaryIndexes(precipIndex);

Table table = dynamoDB.createTable(createTableRequest);
System.out.println(table.getDescription());
```

Anda harus menunggu hingga DynamoDB membuat tabel dan menetapkan status tabel menjadi `ACTIVE`. Setelah itu, Anda bisa mulai memasukkan item data ke dalam tabel.

## Mendeskripsikan tabel dengan Indeks Sekunder Global
<a name="GSIJavaDocumentAPI.DescribeTableWithIndex"></a>

Untuk mendapatkan informasi tentang indeks sekunder global pada sebuah tabel, gunakan `DescribeTable`. Untuk setiap indeks, Anda dapat mengakses namanya, skema kunci, dan atribut yang diproyeksikan.

Berikut ini adalah langkah-langkah untuk mengakses informasi indeks sekunder global sebuah tabel. 

1. Buat instans dari kelas `DynamoDB`.

1. Buat instans dari kelas `Table` untuk mewakili indeks yang ingin Anda gunakan.

1. Panggil metode `describe` pada objek `Table`.

Contoh kode Java berikut mendemonstrasikan langkah sebelumnya.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("WeatherData");
TableDescription tableDesc = table.describe();
    

Iterator<GlobalSecondaryIndexDescription> gsiIter = tableDesc.getGlobalSecondaryIndexes().iterator();
while (gsiIter.hasNext()) {
    GlobalSecondaryIndexDescription gsiDesc = gsiIter.next();
    System.out.println("Info for index "
         + gsiDesc.getIndexName() + ":");

    Iterator<KeySchemaElement> kseIter = gsiDesc.getKeySchema().iterator();
    while (kseIter.hasNext()) {
        KeySchemaElement kse = kseIter.next();
        System.out.printf("\t%s: %s\n", kse.getAttributeName(), kse.getKeyType());
    }
    Projection projection = gsiDesc.getProjection();
    System.out.println("\tThe projection type is: "
        + projection.getProjectionType());
    if (projection.getProjectionType().toString().equals("INCLUDE")) {
        System.out.println("\t\tThe non-key projected attributes are: "
            + projection.getNonKeyAttributes());
    }
}
```

## Mengkueri Indeks Sekunder Global
<a name="GSIJavaDocumentAPI.QueryAnIndex"></a>

Anda dapat menggunakan `Query` pada indeks sekunder global, sama seperti Anda `Query` tabel. Anda perlu menentukan nama indeks, kriteria kueri untuk kunci partisi indeks dan kunci urutan (jika ada), dan atribut yang ingin Anda kembalikan. Dalam contoh ini, indeks adalah `PrecipIndex`, yang memiliki kunci partisi `Date` dan kunci urutan `Precipitation`. Kueri indeks mengembalikan semua data cuaca untuk tanggal tertentu, dengan curah hujan lebih besar dari nol.

Berikut ini adalah langkah-langkah untuk query indeks sekunder global menggunakan AWS SDK untuk Java Document API. 

1. Buat instans dari kelas `DynamoDB`.

1. Buat instans dari kelas `Table` untuk mewakili indeks yang ingin Anda gunakan.

1. Buat instans dari kelas `Index` untuk indeks yang ingin Anda kueri.

1. Panggil metode `query` pada objek `Index`.

Nama atribut `Date` adalah kata yang disimpan DynamoDB. Oleh karena itu, Anda harus menggunakan nama atribut ekspresi sebagai placeholder di `KeyConditionExpression`.

Contoh kode Java berikut mendemonstrasikan langkah sebelumnya.

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("WeatherData");
Index index = table.getIndex("PrecipIndex");

QuerySpec spec = new QuerySpec()
    .withKeyConditionExpression("#d = :v_date and Precipitation = :v_precip")
    .withNameMap(new NameMap()
        .with("#d", "Date"))
    .withValueMap(new ValueMap()
        .withString(":v_date","2013-08-10")
        .withNumber(":v_precip",0));

ItemCollection<QueryOutcome> items = index.query(spec);
Iterator<Item> iter = items.iterator(); 
while (iter.hasNext()) {
    System.out.println(iter.next().toJSONPretty());
}
```

# Contoh: Indeks Sekunder Global menggunakan API AWS SDK untuk Java dokumen
<a name="GSIJavaDocumentAPI.Example"></a>

Contoh kode Java berikut menunjukkan cara menggunakan indeks sekunder global. Contoh tersebut membuat tabel bernama `Issues`, yang dapat digunakan dalam sistem pelacakan bug sederhana untuk pengembangan perangkat lunak. Kunci partisinya adalah `IssueId` dan kunci urutannya adalah `Title`. Ada tiga indeks sekunder global pada tabel ini:
+ `CreateDateIndex` — Kunci partisinya adalah `CreateDate` dan kunci urutannya adalah `IssueId`. Selain kunci tabel, atribut `Description` dan `Status` diproyeksikan ke dalam indeks.
+ `TitleIndex` — Kunci partisinya adalah `Title` dan kunci urutannya adalah `IssueId`. Tidak ada atribut selain kunci tabel yang diproyeksikan ke dalam indeks.
+ `DueDateIndex` — Kunci partisinya adalah `DueDate`, dan tidak ada kunci urutan. Semua atribut tabel diproyeksikan ke dalam indeks.

Setelah tabel `Issues` dibuat, program memuat tabel dengan data yang mewakili laporan bug perangkat lunak. Kemudian, data dikueri menggunakan indeks sekunder global. Terakhir, program menghapus tabel `Issues`.

Untuk step-by-step instruksi untuk menguji contoh berikut, lihat[Contoh kode Java](CodeSamples.Java.md).

**Example**  

```
package com.amazonaws.codesamples.document;

import java.util.ArrayList;
import java.util.Iterator;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
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.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.GlobalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.Projection;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;

public class DocumentAPIGlobalSecondaryIndexExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    public static String tableName = "Issues";

    public static void main(String[] args) throws Exception {

        createTable();
        loadData();

        queryIndex("CreateDateIndex");
        queryIndex("TitleIndex");
        queryIndex("DueDateIndex");

        deleteTable(tableName);

    }

    public static void createTable() {

        // Attribute definitions
        ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();

        attributeDefinitions.add(new AttributeDefinition().withAttributeName("IssueId").withAttributeType("S"));
        attributeDefinitions.add(new AttributeDefinition().withAttributeName("Title").withAttributeType("S"));
        attributeDefinitions.add(new AttributeDefinition().withAttributeName("CreateDate").withAttributeType("S"));
        attributeDefinitions.add(new AttributeDefinition().withAttributeName("DueDate").withAttributeType("S"));

        // Key schema for table
        ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>();
        tableKeySchema.add(new KeySchemaElement().withAttributeName("IssueId").withKeyType(KeyType.HASH)); // Partition
                                                                                                           // key
        tableKeySchema.add(new KeySchemaElement().withAttributeName("Title").withKeyType(KeyType.RANGE)); // Sort
                                                                                                          // key

        // Initial provisioned throughput settings for the indexes
        ProvisionedThroughput ptIndex = new ProvisionedThroughput().withReadCapacityUnits(1L)
                .withWriteCapacityUnits(1L);

        // CreateDateIndex
        GlobalSecondaryIndex createDateIndex = new GlobalSecondaryIndex().withIndexName("CreateDateIndex")
                .withProvisionedThroughput(ptIndex)
                .withKeySchema(new KeySchemaElement().withAttributeName("CreateDate").withKeyType(KeyType.HASH), // Partition
                                                                                                                 // key
                        new KeySchemaElement().withAttributeName("IssueId").withKeyType(KeyType.RANGE)) // Sort
                                                                                                        // key
                .withProjection(
                        new Projection().withProjectionType("INCLUDE").withNonKeyAttributes("Description", "Status"));

        // TitleIndex
        GlobalSecondaryIndex titleIndex = new GlobalSecondaryIndex().withIndexName("TitleIndex")
                .withProvisionedThroughput(ptIndex)
                .withKeySchema(new KeySchemaElement().withAttributeName("Title").withKeyType(KeyType.HASH), // Partition
                                                                                                            // key
                        new KeySchemaElement().withAttributeName("IssueId").withKeyType(KeyType.RANGE)) // Sort
                                                                                                        // key
                .withProjection(new Projection().withProjectionType("KEYS_ONLY"));

        // DueDateIndex
        GlobalSecondaryIndex dueDateIndex = new GlobalSecondaryIndex().withIndexName("DueDateIndex")
                .withProvisionedThroughput(ptIndex)
                .withKeySchema(new KeySchemaElement().withAttributeName("DueDate").withKeyType(KeyType.HASH)) // Partition
                                                                                                              // key
                .withProjection(new Projection().withProjectionType("ALL"));

        CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(tableName)
                .withProvisionedThroughput(
                        new ProvisionedThroughput().withReadCapacityUnits((long) 1).withWriteCapacityUnits((long) 1))
                .withAttributeDefinitions(attributeDefinitions).withKeySchema(tableKeySchema)
                .withGlobalSecondaryIndexes(createDateIndex, titleIndex, dueDateIndex);

        System.out.println("Creating table " + tableName + "...");
        dynamoDB.createTable(createTableRequest);

        // Wait for table to become active
        System.out.println("Waiting for " + tableName + " to become ACTIVE...");
        try {
            Table table = dynamoDB.getTable(tableName);
            table.waitForActive();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void queryIndex(String indexName) {

        Table table = dynamoDB.getTable(tableName);

        System.out.println("\n***********************************************************\n");
        System.out.print("Querying index " + indexName + "...");

        Index index = table.getIndex(indexName);

        ItemCollection<QueryOutcome> items = null;

        QuerySpec querySpec = new QuerySpec();

        if (indexName == "CreateDateIndex") {
            System.out.println("Issues filed on 2013-11-01");
            querySpec.withKeyConditionExpression("CreateDate = :v_date and begins_with(IssueId, :v_issue)")
                    .withValueMap(new ValueMap().withString(":v_date", "2013-11-01").withString(":v_issue", "A-"));
            items = index.query(querySpec);
        } else if (indexName == "TitleIndex") {
            System.out.println("Compilation errors");
            querySpec.withKeyConditionExpression("Title = :v_title and begins_with(IssueId, :v_issue)")
                    .withValueMap(
                            new ValueMap().withString(":v_title", "Compilation error").withString(":v_issue", "A-"));
            items = index.query(querySpec);
        } else if (indexName == "DueDateIndex") {
            System.out.println("Items that are due on 2013-11-30");
            querySpec.withKeyConditionExpression("DueDate = :v_date")
                    .withValueMap(new ValueMap().withString(":v_date", "2013-11-30"));
            items = index.query(querySpec);
        } else {
            System.out.println("\nNo valid index name provided");
            return;
        }

        Iterator<Item> iterator = items.iterator();

        System.out.println("Query: printing results...");

        while (iterator.hasNext()) {
            System.out.println(iterator.next().toJSONPretty());
        }

    }

    public static void deleteTable(String tableName) {

        System.out.println("Deleting table " + tableName + "...");

        Table table = dynamoDB.getTable(tableName);
        table.delete();

        // Wait for table to be deleted
        System.out.println("Waiting for " + tableName + " to be deleted...");
        try {
            table.waitForDelete();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void loadData() {

        System.out.println("Loading data into table " + tableName + "...");

        // IssueId, Title,
        // Description,
        // CreateDate, LastUpdateDate, DueDate,
        // Priority, Status

        putItem("A-101", "Compilation error", "Can't compile Project X - bad version number. What does this mean?",
                "2013-11-01", "2013-11-02", "2013-11-10", 1, "Assigned");

        putItem("A-102", "Can't read data file", "The main data file is missing, or the permissions are incorrect",
                "2013-11-01", "2013-11-04", "2013-11-30", 2, "In progress");

        putItem("A-103", "Test failure", "Functional test of Project X produces errors", "2013-11-01", "2013-11-02",
                "2013-11-10", 1, "In progress");

        putItem("A-104", "Compilation error", "Variable 'messageCount' was not initialized.", "2013-11-15",
                "2013-11-16", "2013-11-30", 3, "Assigned");

        putItem("A-105", "Network issue", "Can't ping IP address 127.0.0.1. Please fix this.", "2013-11-15",
                "2013-11-16", "2013-11-19", 5, "Assigned");

    }

    public static void putItem(

            String issueId, String title, String description, String createDate, String lastUpdateDate, String dueDate,
            Integer priority, String status) {

        Table table = dynamoDB.getTable(tableName);

        Item item = new Item().withPrimaryKey("IssueId", issueId).withString("Title", title)
                .withString("Description", description).withString("CreateDate", createDate)
                .withString("LastUpdateDate", lastUpdateDate).withString("DueDate", dueDate)
                .withNumber("Priority", priority).withString("Status", status);

        table.putItem(item);
    }

}
```