

# Trabajo con índices secundarios globales: Java
<a name="GSIJavaDocumentAPI"></a>

Puede utilizar la API de documentos AWS SDK para Java para crear una tabla Amazon DynamoDB con uno o varios índices secundarios globales, describir los índices de la tabla y utilizarlos para realizar consultas. 

A continuación se indican los pasos comunes para las operaciones con tablas. 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree los objetos de solicitud correspondientes para proporcionar los parámetros obligatorios y opcionales de la operación. 

1. Llame al método apropiado proporcionado por el cliente que ha creado en el paso anterior. 

**Topics**
+ [Creación de una tabla con un índice secundario global](#GSIJavaDocumentAPI.CreateTableWithIndex)
+ [Descripción de una tabla con un índice secundario global](#GSIJavaDocumentAPI.DescribeTableWithIndex)
+ [Consulta de un índice secundario local](#GSIJavaDocumentAPI.QueryAnIndex)
+ [Ejemplo: índices secundarios globales que utilizan la API de documentos de AWS SDK para Java](GSIJavaDocumentAPI.Example.md)

## Creación de una tabla con un índice secundario global
<a name="GSIJavaDocumentAPI.CreateTableWithIndex"></a>

Puede crear índices secundarios globales a la vez que crea la tabla. Para ello, utilice `CreateTable` e indique las especificaciones para uno o varios índices secundarios globales. En el ejemplo de código Java siguiente, se crea una tabla para contener información sobre datos meteorológicos. La clave de partición es `Location` y la de ordenación, `Date`. Un índice secundario global denominado `PrecipIndex` permite obtener acceso rápido a los datos sobre precipitaciones de varias ubicaciones.

A continuación se indican los pasos que hay que seguir para crear una tabla con un índice secundario global mediante el API de documentos de DynamoDB. 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `CreateTableRequest` para proporcionar la información de solicitud.

   Debe proporcionar el nombre de la tabla, su clave principal y los valores de rendimiento aprovisionado. Para el índice secundario global, debe proporcionar el nombre del índice, los ajustes de rendimiento aprovisionado, las definiciones de atributos de la clave de ordenación del índice, el esquema de claves del índice y la proyección de atributos.

1. Llame al método `createTable` proporcionando el objeto de solicitud como parámetro.

En el siguiente ejemplo de código Java se muestran los pasos anteriores. El código crea una tabla (`WeatherData`) con un índice secundario global (`PrecipIndex`). La clave de partición del índice es `Date` y la de ordenación, `Precipitation`. Todos los atributos de la tabla se proyectan en el índice. Los usuarios pueden consultar este índice para obtener los datos meteorológicos de una determinada fecha y, si lo desean, ordenarlos según la cantidad de precipitación. 

Ya que `Precipitation` no es un atributo de clave para la tabla, no es obligatorio. Sin embargo, los elementos`WeatherData` sin `Precipitation` no aparecen en `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());
```

Debe esperar hasta que DynamoDB cree la tabla y establezca el estado de esta última en `ACTIVE`. A partir de ese momento, puede comenzar a incluir elementos de datos en la tabla.

## Descripción de una tabla con un índice secundario global
<a name="GSIJavaDocumentAPI.DescribeTableWithIndex"></a>

Para obtener información sobre los índices secundarios globales en una tabla, use `DescribeTable`. Para cada índice, puede obtener acceso a su nombre, esquema de claves y atributos proyectados.

Los siguientes son los pasos para acceder a la información global de índice secundario de una tabla. 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `Table` para representar el índice que desea usar.

1. Llame al método `describe` del objeto `Table`.

En el siguiente ejemplo de código Java se muestran los pasos anteriores.

**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());
    }
}
```

## Consulta de un índice secundario local
<a name="GSIJavaDocumentAPI.QueryAnIndex"></a>

Puede utilizar `Query` en un índice secundario global, de un modo bastante similar al que realiza una `Query` en una tabla. Debe especificar el nombre del índice, los criterios de consulta de la clave de partición y la clave de ordenación (si procede) del índice y los atributos que desea devolver. En este ejemplo, el índice es `PrecipIndex`, cuyas clave de partición y ordenación son, respectivamente, `Date` y `Precipitation`. La consulta del índice devuelve todos los datos meteorológicos de una determinada fecha cuando el valor de Precipitation sea mayor que cero.

A continuación se indican los pasos que hay que seguir para consultar un índice secundario global mediante la API Document de AWS SDK para Java. 

1. Cree una instancia de la clase `DynamoDB`.

1. Cree una instancia de la clase `Table` para representar el índice que desea usar.

1. Cree una instancia de la clase `Index` para el índice que desea consultar.

1. Llame al método `query` del objeto `Index`.

El nombre de atributo `Date` es una palabra reservada de DynamoDB. Por consiguiente, debe usar un nombre de atributo de expresión como marcador de posición en la expresión `KeyConditionExpression`.

En el siguiente ejemplo de código Java se muestran los pasos anteriores.

**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());
}
```