This topic describes how to use the Go SDK of Table Store to create, query, or delete a global secondary index.

Create a global secondary index

  • Create a global secondary index when you create a primary table
    Example:
    func CreateTableWithGlobalIndexSample(client *tablestore.TableStoreClient, tableName string) {
        createTableRequest := new(tablestore.CreateTableRequest)
    
        tableMeta := new(tablestore.TableMeta)
        tableMeta.TableName = tableName
        tableMeta.AddPrimaryKeyColumn("pk1", tablestore.PrimaryKeyType_STRING)
        tableMeta.AddPrimaryKeyColumn("pk2", tablestore.PrimaryKeyType_INTEGER)
        tableMeta.AddDefinedColumn("definedcol1", tablestore.DefinedColumn_STRING)
        tableMeta.AddDefinedColumn("definedcol2", tablestore.DefinedColumn_INTEGER)
    
        indexMeta := new(tablestore.IndexMeta) // Create a global secondary index named Meta.
        indexMeta.AddPrimaryKeyColumn("definedcol1") // Specify the DEFINED_COL_NAME_1 column of the primary table as a primary key column of the index.
        indexMeta.AddDefinedColumn("definedcol2") // Specify the DEFINED_COL_NAME_2 column of the primary table as an attribute column of the index.
        indexMeta.IndexName = "indexSample"
    
        tableOption := new(tablestore.TableOption)
        tableOption.TimeToAlive = -1 // Specify the validity period of data. The value of -1 indicates that the data never expires.
        tableOption.MaxVersion = 1 // Specify the maximum number of versions that can be saved in each column. The value of 1 indicates that only the latest version is saved in each column.
        reservedThroughput := new(tablestore.ReservedThroughput)
    
        createTableRequest.TableMeta = tableMeta
        createTableRequest.TableOption = tableOption
        createTableRequest.ReservedThroughput = reservedThroughput
        createTableRequest.AddIndexMeta(indexMeta)
    
        _, err := client.CreateTable(createTableRequest)
        if err ! = nil {
            fmt.Println("Failed to create table with error:", err)
        } else {
            fmt.Println("Create table finished")
        }
    }
  • Create a global secondary index for an existing table
    You can create a global secondary index for an existing primary table. Example:
    func CreateGlobalIndexSample(client *tablestore.TableStoreClient, tableName string) {
        indexMeta := new(tablestore.IndexMeta) // Create a global secondary index named Meta.
        indexMeta.AddPrimaryKeyColumn("definedcol1") // Specify the DEFINED_COL_NAME_1 column of the primary table as a primary key column of the index.
        indexMeta.AddDefinedColumn("definedcol2") // Specify the DEFINED_COL_NAME_2 column of the primary table as an attribute column of the index.
        indexMeta.IndexName = "indexSample"
        indexReq := &tablestore.CreateIndexRequest{
            MainTableName:tableName, // Add the index to the primary table.
            IndexMeta: indexMeta,
            IncludeBaseData: true, // Specify that the existing data of the primary table is included in the index.
        }
        /**
          You can set the IncludeBaseData parameter to true to enable the synchronization of existing data in the primary table after an index is created. You can then query all data by using the global secondary index.
          The time required to synchronize data to the index is determined by the amount of data in the primary table.
        */  
        resp, err := client.CreateIndex(indexReq)
        if err ! = nil {
            fmt.Println("Failed to create table with error:", err)
        } else {
            fmt.Println("Create index finished", resp)
        }
    }
    Note When you create an index for the primary table, you can choose whether to include the existing data of the primary table. When the IncludeBaseData parameter of CreateInexRequest is set to true, the index includes the existing data. When the value is false, the index does not include the existing data.

Delete a global secondary index

You can delete a global secondary index from a primary table. Example:
func DeleteIndex(client *tablestore.TableStoreClient, tableName string, indexName string) { 
    deleteIndex := &tablestore.DeleteIndexRequest{ MainTableName:tableName, IndexName: indexName }
    resp, err := client.DeleteIndex(deleteIndex)

    if err ! = nil {
        fmt.Println("Failed to delete index:", err)
    } else {
        fmt.Println("drop index finished", resp)
    }

Query a global secondary index

Example:
func GetRangeFromIndex(client *tablestore.TableStoreClient, indexName string) {
    getRangeRequest := &tablestore.GetRangeRequest{}
    rangeRowQueryCriteria := &tablestore.RangeRowQueryCriteria{}
    rangeRowQueryCriteria.TableName = indexName

    startPK := new(tablestore.PrimaryKey)
    startPK.AddPrimaryKeyColumnWithMinValue("pk1") // Specify the pk1 of the index.
    startPK.AddPrimaryKeyColumnWithMinValue("pk2") // Specify the pk2 of the index.
    startPK.AddPrimaryKeyColumnWithMinValue("pk3") // Specify the pk3 of the index.
    endPK := new(tablestore.PrimaryKey)
    endPK.AddPrimaryKeyColumnWithMaxValue("pk1")
    endPK.AddPrimaryKeyColumnWithMaxValue("pk2")
    endPK.AddPrimaryKeyColumnWithMaxValue("pk3")
    rangeRowQueryCriteria.StartPrimaryKey = startPK
    rangeRowQueryCriteria.EndPrimaryKey = endPK
    rangeRowQueryCriteria.Direction = tablestore.FORWARD
    rangeRowQueryCriteria.MaxVersion = 1
    rangeRowQueryCriteria.Limit = 10
    getRangeRequest.RangeRowQueryCriteria = rangeRowQueryCriteria

    getRangeResp, err := client.GetRange(getRangeRequest)

    fmt.Println("get range result is ", getRangeResp)

    for {
        if err ! = nil {
            fmt.Println("get range failed with error:", err)
        }
        if len(getRangeResp.Rows) > 0 {
            for _, row := range getRangeResp.Rows {
                fmt.Println("range get row with key", row.PrimaryKey.PrimaryKeys[0].Value, row.PrimaryKey.PrimaryKeys[1].Value, row.PrimaryKey.PrimaryKeys[2].Value)
            }
            if getRangeResp.NextStartPrimaryKey == nil {
                break
            } else {
                fmt.Println("next pk is :", getRangeResp.NextStartPrimaryKey.PrimaryKeys[0].Value, getRangeResp.NextStartPrimaryKey.PrimaryKeys[1].Value, getRangeResp.NextStartPrimaryKey.PrimaryKeys[2].Value)
                getRangeRequest.RangeRowQueryCriteria.StartPrimaryKey = getRangeResp.NextStartPrimaryKey
                getRangeResp, err = client.GetRange(getRangeRequest)
            }
        } else {
            break
        }

        fmt.Println("continue to query rows")
    }
    fmt.Println("putrow finished")
}