Indeks pencarian memungkinkan Anda melakukan kueri data berdasarkan kolom non-primary key dan beberapa kondisi. Topik ini menggunakan data produk sebagai contoh untuk menunjukkan cara membuat tabel data dan indeks pencarian, menulis data, serta menjalankan kueri tepat menggunakan Tablestore SDK untuk Java.
Persiapan
Aktifkan Tablestore dan buat instans. Untuk informasi selengkapnya, lihat Aktifkan layanan dan buat instans.
Instal Tablestore SDK untuk Java, inisialisasi client, dan peroleh instans
SyncClient. Untuk informasi selengkapnya, lihat Java SDK.
Prosedur
Pada contoh ini, Anda membuat tabel data bernama example_table dan indeks pencarian bernama example_index. Setelah indeks pencarian siap, Anda menulis tiga baris data produk dan melakukan kueri terhadap baris-baris yang nilai kolom category-nya adalah books.
Tambahkan metode sampel pada langkah-langkah berikut ke dalam aplikasi Java tempat client diinisialisasi, lalu panggil metode tersebut sesuai urutan berikut:
private static void runQuickStart(SyncClient client)
throws InterruptedException {
String tableName = "example_table";
String indexName = "example_index";
createTable(client, tableName);
createSearchIndex(client, tableName, indexName);
waitUntilSearchIndexIsReady(client, tableName, indexName);
putSampleRows(client, tableName);
SearchResponse response =
waitUntilBooksAreQueryable(client, tableName, indexName);
System.out.println("Total count: " + response.getTotalCount());
System.out.println("Rows: " + response.getRows());
}
Langkah 1: Buat tabel data
Untuk membuat indeks pencarian pada tabel data, Anda harus mengatur jumlah maksimum versi menjadi 1 serta mengatur time to live (TTL) tabel data menjadi -1, yang berarti data tidak pernah kedaluwarsa, atau menonaktifkan pembaruan data. Pada contoh ini, jumlah maksimum versi diatur menjadi 1 dan TTL diatur menjadi -1.
private static void createTable(
SyncClient client, String tableName) {
TableMeta tableMeta = new TableMeta(tableName);
tableMeta.addPrimaryKeyColumn(
new PrimaryKeySchema(
"product_id", PrimaryKeyType.STRING));
TableOptions tableOptions = new TableOptions();
tableOptions.setTimeToLive(-1);
tableOptions.setMaxVersions(1);
client.createTable(
new CreateTableRequest(tableMeta, tableOptions));
}
Langkah 2: Buat indeks pencarian
Buat bidang indeks untuk kolom atribut category dan price. Nama dan tipe data bidang indeks harus sama dengan kolom atribut yang sesuai di tabel data.
private static void createSearchIndex(
SyncClient client, String tableName, String indexName) {
IndexSchema indexSchema = new IndexSchema();
indexSchema.setFieldSchemas(Arrays.asList(
new FieldSchema("category", FieldType.KEYWORD),
new FieldSchema("price", FieldType.LONG)));
CreateSearchIndexRequest request =
new CreateSearchIndexRequest();
request.setTableName(tableName);
request.setIndexName(indexName);
request.setIndexSchema(indexSchema);
client.createSearchIndex(request);
}
Indeks pencarian dibuat secara asinkron. Tunggu hingga status indeks berubah menjadi RUNNING dan fase sinkronisasi berubah menjadi INCR sebelum melakukan kueri data.
private static final int RETRY_ATTEMPTS = 90;
private static final long RETRY_INTERVAL_MILLIS = 1_000L;
private static void waitUntilSearchIndexIsReady(
SyncClient client, String tableName, String indexName)
throws InterruptedException {
for (int attempt = 1; attempt <= RETRY_ATTEMPTS; attempt++) {
DescribeSearchIndexRequest request =
new DescribeSearchIndexRequest();
request.setTableName(tableName);
request.setIndexName(indexName);
request.setIncludeSyncStat(true);
DescribeSearchIndexResponse response =
client.describeSearchIndex(request);
if (response.getIndexStatus() != null
&& response.getIndexStatus().indexStatusEnum
== DescribeSearchIndexResponse.IndexStatusEnum.RUNNING
&& response.getSyncStat() != null
&& response.getSyncStat().getSyncPhase()
== SyncStat.SyncPhase.INCR) {
return;
}
Thread.sleep(RETRY_INTERVAL_MILLIS);
}
throw new IllegalStateException(
"Search index did not become ready before timeout.");
}
Langkah 3: Tulis data sampel
Tulis tiga baris data produk. Kolom product_id adalah kolom kunci primer, sedangkan kolom category dan price adalah kolom atribut.
private static void putSampleRows(
SyncClient client, String tableName) {
putProduct(client, tableName, "product-001", "books", 89L);
putProduct(client, tableName, "product-002", "books", 129L);
putProduct(client, tableName, "product-003", "devices", 599L);
}
private static void putProduct(
SyncClient client,
String tableName,
String productId,
String category,
long price) {
PrimaryKey primaryKey =
PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn(
"product_id",
PrimaryKeyValue.fromString(productId))
.build();
RowPutChange rowPutChange =
new RowPutChange(tableName, primaryKey);
rowPutChange.addColumn(
"category", ColumnValue.fromString(category));
rowPutChange.addColumn(
"price", ColumnValue.fromLong(price));
client.putRow(new PutRowRequest(rowPutChange));
}
Langkah 4: Kueri data
Jalankan kueri tepat untuk mencocokkan baris-baris yang nilai kolom category-nya adalah books. Sinkronisasi data ke indeks pencarian memerlukan waktu singkat. Kode sampel akan mencoba ulang kueri jika hasilnya belum siap.
private static SearchResponse waitUntilBooksAreQueryable(
SyncClient client, String tableName, String indexName)
throws InterruptedException {
for (int attempt = 1; attempt <= RETRY_ATTEMPTS; attempt++) {
SearchResponse response =
queryBooks(client, tableName, indexName);
if (response.isAllSuccess()
&& response.getTotalCount() == 2L
&& response.getRows().size() == 2) {
return response;
}
Thread.sleep(RETRY_INTERVAL_MILLIS);
}
throw new IllegalStateException(
"Sample rows were not queryable before timeout.");
}
private static SearchResponse queryBooks(
SyncClient client, String tableName, String indexName) {
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("category");
termQuery.setTerm(ColumnValue.fromString("books"));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(termQuery);
searchQuery.setLimit(10);
searchQuery.setTrackTotalCount(
SearchQuery.TRACK_TOTAL_COUNT);
SearchRequest.ColumnsToGet columnsToGet =
new SearchRequest.ColumnsToGet();
columnsToGet.setReturnAll(true);
SearchRequest request =
new SearchRequest(tableName, indexName, searchQuery);
request.setColumnsToGet(columnsToGet);
return client.search(request);
}
Jika jumlah total baris yang cocok dan jumlah baris yang dikembalikan keduanya bernilai 2, kueri berhasil.
Bersihkan sumber daya
Jika Anda tidak lagi memerlukan sumber daya sampel, hapus indeks pencarian sebelum menghapus tabel data.
DeleteSearchIndexRequest deleteIndexRequest =
new DeleteSearchIndexRequest();
deleteIndexRequest.setTableName("example_table");
deleteIndexRequest.setIndexName("example_index");
client.deleteSearchIndex(deleteIndexRequest);
client.deleteTable(new DeleteTableRequest("example_table"));
client.shutdown();
Langkah selanjutnya
Untuk informasi tentang cara kerja indeks pencarian, kasus penggunaan, dan batasannya, lihat Indeks pencarian.
Untuk informasi tentang pengurutan indeks, TTL, kolom virtual, dan fitur indeks lainnya, lihat Buat indeks pencarian.
Untuk informasi tentang jenis kueri lainnya serta cara mengurutkan, mengagregasi, atau menghapus duplikat hasil kueri, lihat Kueri data.