Dynamically modify a schema

更新时间:
复制 MD 格式

Changing a field type in an existing search index requires rebuilding the index. Create a grayscale index with the updated schema using the Tablestore Java SDK, then complete the switch in the Tablestore console — with no downtime to your application.

How reindex works

When you modify a schema, Tablestore creates a grayscale index alongside the source index and rebuilds all historical data into it. During this process:

  1. The system copies all existing data from the source index into the grayscale index using the new schema.

  2. Ongoing writes are synchronized to both indexes until you complete the switch.

  3. After you swap the indexes in the console, the grayscale index becomes the active index and the source index is removed.

This approach lets you validate the new schema — and optionally run A/B tests — before committing to the change.

Constraints

  • You can rebuild up to five indexes concurrently. Wait for all five to complete before starting another batch.

  • A rebuild is complete when the data volume of the grayscale index matches the source index in the console, or when you finish the index switch.

  • The grayscale index name must end with _reindex.

Modify a schema

Step 1: Create a grayscale index

Create a grayscale index based on the source index. Set setSourceIndexName to link the grayscale index to its source, then define the new schema by adding, updating, or removing fields.

// This example shows how to create a grayscale index (reindex) to dynamically modify a search index schema.
// Before you run this code, set the environment variables TABLESTORE_ACCESS_KEY_ID and TABLESTORE_ACCESS_KEY_SECRET.

import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.CredentialsProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentialProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentials;
import com.alicloud.openservices.tablestore.core.auth.V4Credentials;
import com.alicloud.openservices.tablestore.model.search.CreateSearchIndexRequest;
import com.alicloud.openservices.tablestore.model.search.CreateSearchIndexResponse;
import com.alicloud.openservices.tablestore.model.search.FieldSchema;
import com.alicloud.openservices.tablestore.model.search.FieldType;
import com.alicloud.openservices.tablestore.model.search.IndexSchema;
import com.alicloud.openservices.tablestore.model.search.IndexSetting;

import java.util.Arrays;

public class CreateReindex {

    public static void main(String[] args) {
        String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");

        // Instance configuration
        String region = "<region-id>";
        String instanceName = "example-instance";
        String endpoint = "https://example-instance.<region-id>.ots.aliyuncs.com";

        // Table name and index name
        String tableName = "example_table";
        String sourceIndexName = "example_index";
        // The grayscale index name must end with _reindex
        String reindexName = sourceIndexName + "_reindex";

        SyncClient client = null;
        try {
            DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
            V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
            client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // Create a grayscale index request
            CreateSearchIndexRequest request = new CreateSearchIndexRequest();
            request.setTableName(tableName);
            request.setIndexName(reindexName);
            // Specify the source index to indicate that this is a grayscale index built from the source index
            request.setSourceIndexName(sourceIndexName);

            // Define the new index schema (add, update, or delete fields)
            IndexSchema indexSchema = new IndexSchema();
            indexSchema.setFieldSchemas(Arrays.asList(
                    new FieldSchema("pk", FieldType.KEYWORD).setIndex(true).setEnableSortAndAgg(true),
                    new FieldSchema("col1", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true),
                    // Add col3 (the original index has only pk, col1, and col2)
                    new FieldSchema("col3", FieldType.LONG).setIndex(true).setEnableSortAndAgg(true)
            ));

            // Set routing fields (to optimize query performance)
            IndexSetting indexSetting = new IndexSetting();
            indexSetting.setRoutingFields(Arrays.asList("pk"));
            indexSchema.setIndexSetting(indexSetting);

            request.setIndexSchema(indexSchema);

            // Create the grayscale index
            CreateSearchIndexResponse response = client.createSearchIndex(request);
            System.out.println("Grayscale index created: " + reindexName);
            System.out.println("RequestId: " + response.getRequestId());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (client != null) {
                client.shutdown();
            }
        }
    }
}

Step 2: Complete the switch in the console

After the grayscale index finishes rebuilding, use the Tablestore console to check the sync progress, assign weights for A/B testing, swap schemas between indexes, and delete the grayscale index. For more information, see Dynamically modify a schema.