Saat melakukan kueri terhadap indeks pencarian menggunakan Tablestore SDK untuk Java, gunakan index sort atau query-time sort untuk mengatur urutan hasil, serta offset atau token untuk membagi hasil menjadi beberapa halaman.
Prasyarat
Instal Tablestore SDK untuk Java dan inisialisasi client.
Cara kerja
Indeks pencarian mendukung mekanisme pengurutan berikut:
Index sort: Saat membuat indeks pencarian, konfigurasikan
IndexSchema.indexSortuntuk menentukan urutan hasil default. Jika index sort tidak dikonfigurasi, hasil diurutkan berdasarkan primary key. Index sort hanya mendukungPrimaryKeySortdanFieldSort. Indeks pencarian yang berisi bidang Nested tidak mendukung index sort.Query-time sort: Konfigurasikan
SearchQuery.sortuntuk kueri individual. Hasil dapat diurutkan berdasarkan skor relevansi, primary key, nilai bidang, atau jarak geografis. Beberapa sorter dapat digabungkan untuk pengurutan multi-level. Kecuali untuk bidang primary key, bidang yang digunakan untuk pengurutan harus memilikienableSortAndAggdiatur ketruedalam skema indeks pencarian.
Ketika sorter selain primary key sorter ditentukan pada waktu kueri, server secara default menambahkan primary key sorter agar baris dengan nilai pengurutan yang sama memiliki urutan yang deterministik. Untuk menonaktifkan perilaku ini, atur Sort.disableDefaultPkSorter ke true.
Gunakan salah satu metode paginasi berikut untuk set hasil yang besar:
|
Metode |
Kasus penggunaan |
Karakteristik |
|
limit and offset |
Set hasil berisi tidak lebih dari 100.000 baris dan posisi tertentu harus diakses. |
Mendukung lompat halaman. Jumlah |
|
token |
Paginasi dalam (deep pagination) atau membaca semua hasil secara berurutan. |
Tidak memiliki batas kedalaman 100.000 baris, tetapi hasil hanya dapat dibaca secara berurutan. |
Panggil metode search untuk melakukan kueri data.
SearchResponse search(SearchRequest request)
Contoh berikut mengembalikan 10 baris pertama yang diurutkan berdasarkan bidang score secara descending, lalu berdasarkan primary key secara ascending.
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(10);
searchQuery.setSort(new Sort(Arrays.<Sort.Sorter>asList(
new FieldSort("score", SortOrder.DESC),
new PrimaryKeySort(SortOrder.ASC))));
SearchRequest request =
new SearchRequest("example_table", "example_index", searchQuery);
SearchResponse response = client.search(request);
Parameter
Permintaan kueri
Tipe request adalah SearchRequest. Tabel berikut menjelaskan parameter-parameternya.
|
Nama |
Type |
Deskripsi |
|
tableName (wajib) |
String |
Nama tabel data. |
|
indexName (wajib) |
String |
Nama indeks pencarian. |
|
searchQuery (wajib) |
SearchQuery |
Kondisi kueri serta konfigurasi pengurutan dan paginasi. |
|
columnsToGet (opsional) |
SearchRequest.ColumnsToGet |
Kolom yang akan dikembalikan. Jika parameter ini tidak dikonfigurasi, hanya kolom kunci primer yang dikembalikan. |
Konfigurasi kueri
Tipe request.searchQuery adalah SearchQuery. Tabel berikut hanya menjelaskan parameter yang terkait dengan pengurutan dan paginasi.
|
Nama |
Tipe |
Deskripsi |
|
query (wajib) |
Query |
Kondisi kueri. |
|
sort (opsional) |
Sort |
Konfigurasi query-time sort. Jika parameter ini tidak dikonfigurasi, index sort yang digunakan. Jangan konfigurasi parameter ini untuk paginasi berbasis token. Setelah |
|
offset (opsional) |
Integer |
Posisi awal kueri saat ini. Nilai default: |
|
limit (opsional) |
Integer |
Jumlah maksimum baris yang dikembalikan. Nilai default: |
|
token (opsional) |
byte[] |
Token paginasi. Atur parameter ini ke nilai |
|
trackTotalCount (opsional) |
int |
Jumlah maksimum baris yang cocok yang diharapkan untuk dihitung. Nilai default: |
Konfigurasi pengurutan
Tipe request.searchQuery.sort adalah Sort. Tabel berikut menjelaskan parameternya.
|
Nama |
Tipe |
Deskripsi |
|
sorters (wajib) |
|
Daftar sorter. Urutan daftar menentukan prioritas pengurutan multi-level. Sorter yang didukung adalah |
|
disableDefaultPkSorter (opsional) |
Boolean |
Menentukan apakah akan mencegah server secara otomatis menambahkan primary key sorter. Nilai default: |
Pengurutan berdasarkan skor relevansi
ScoreSort mengurutkan baris berdasarkan skor relevansi yang dihitung menggunakan algoritma BM25. Tabel berikut menjelaskan parameternya.
|
Nama |
Tipe |
Deskripsi |
|
order (opsional) |
SortOrder |
Urutan pengurutan. |
Untuk mengurutkan berdasarkan skor relevansi, konfigurasikan secara eksplisit ScoreSort. Jika tidak, index sort yang digunakan.
Pengurutan berdasarkan primary key
PrimaryKeySort mengurutkan baris berdasarkan primary key. Tabel berikut menjelaskan parameternya.
|
Nama |
Tipe |
Deskripsi |
|
order (opsional) |
SortOrder |
Urutan pengurutan. Nilai default: |
Pengurutan berdasarkan bidang
FieldSort mengurutkan baris berdasarkan nilai bidang. Tabel berikut menjelaskan parameternya.
|
Nama |
Type |
Deskripsi |
|
fieldName (wajib) |
String |
Nama bidang pengurutan. Pengurutan dan agregasi harus diaktifkan untuk bidang tersebut. |
|
order (opsional) |
SortOrder |
Urutan pengurutan. Nilai default: |
|
mode (opsional) |
SortMode |
Nilai yang digunakan saat mengurutkan bidang bernilai ganda. |
|
missingFields (opsional) |
|
Daftar bidang cadangan untuk pengurutan. Jika bidang pengurutan saat ini tidak tersedia, bidang pertama dalam daftar yang memiliki nilai akan digunakan. Bidang cadangan harus memiliki tipe yang sama dengan bidang pengurutan. |
|
missingValue (opsional) |
ColumnValue |
Nilai pengurutan yang digunakan jika bidang pengurutan dan semua bidang cadangan tidak tersedia. Atur parameter ini ke |
|
nestedFilter (opsional) |
NestedFilter |
Konfigurasi pengurutan Nested yang menentukan path Nested dan baris anak yang berpartisipasi dalam pengurutan. Konfigurasikan parameter ini hanya saat mengurutkan subfield Nested. |
Filter Nested
Tipe FieldSort.nestedFilter adalah NestedFilter. Tabel berikut menjelaskan parameternya.
|
Nama |
Type |
Deskripsi |
|
path (wajib) |
String |
Path bidang Nested. |
|
query (wajib) |
Query |
Kondisi kueri yang memilih baris anak Nested yang berpartisipasi dalam pengurutan. Atur parameter ke |
Pengurutan berdasarkan jarak geografis
GeoDistanceSort mengurutkan baris berdasarkan jarak antara bidang titik geografis dan titik target. Tabel berikut menjelaskan parameternya.
|
Nama |
Type |
Deskripsi |
|
fieldName (wajib) |
String |
Nama bidang Geopoint. |
|
points (wajib) |
|
Titik geografis target. Setiap titik menggunakan format |
|
order (opsional) |
SortOrder |
Urutan pengurutan. |
|
mode (opsional) |
SortMode |
Nilai yang digunakan saat terdapat beberapa jarak. Nilai yang didukung adalah |
|
distanceType (opsional) |
GeoDistanceType |
Metode perhitungan jarak. |
|
nestedFilter (opsional) |
NestedFilter |
Konfigurasi pengurutan Nested. Konfigurasikan parameter ini hanya saat mengurutkan subfield Nested. |
Kolom yang dikembalikan
Tipe request.columnsToGet adalah SearchRequest.ColumnsToGet. Apakah kolom yang dikembalikan harus dibaca dari tabel data memengaruhi nilai limit maksimum.
|
Nama |
Tipe |
Deskripsi |
|
columns (opsional) |
|
Nama kolom atribut yang dikembalikan. Data hanya dapat dibaca langsung dari indeks pencarian jika semua kolom atribut yang ditentukan telah diindeks dan memiliki store diaktifkan. |
|
returnAll (opsional) |
boolean |
Menentukan apakah akan mengembalikan semua kolom atribut dalam tabel data. Nilai default: |
|
returnAllFromIndex (opsional) |
boolean |
Menentukan apakah akan mengembalikan semua kolom atribut yang disimpan dalam indeks pencarian. Nilai default: |
Respons
Metode search mengembalikan SearchResponse. Tabel berikut menjelaskan bidang yang terkait dengan pengurutan dan paginasi.
|
Nama |
Tipe |
Deskripsi |
|
rows |
|
Baris yang dikembalikan oleh kueri saat ini. Panggil |
|
searchHits |
|
Hasil pencarian. Panggil |
|
totalCount |
long |
Jumlah baris yang cocok. Panggil |
|
nextToken |
byte[] |
Token untuk halaman berikutnya. Panggil |
|
isAllSuccess |
boolean |
Menunjukkan apakah semua partisi indeks telah dikueri. Panggil |
Contoh
Konfigurasi index sort
Contoh berikut mengonfigurasi bidang score sebagai bidang index sort saat membuat indeks pencarian. Jika sort tidak dikonfigurasi untuk kueri, hasil dikembalikan dalam urutan ascending berdasarkan score.
FieldSchema score = new FieldSchema("score", FieldType.LONG)
.setEnableSortAndAgg(true);
IndexSchema indexSchema = new IndexSchema();
indexSchema.setFieldSchemas(Collections.singletonList(score));
indexSchema.setIndexSort(new Sort(
Collections.<Sort.Sorter>singletonList(
new FieldSort("score", SortOrder.ASC))));
Urutkan berdasarkan skor relevansi
Contoh berikut mengembalikan hasil dalam urutan descending berdasarkan skor relevansi BM25.
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("category");
termQuery.setTerm(ColumnValue.fromString("book"));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(termQuery);
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(new ScoreSort())));
Menangani nilai bidang yang tidak tersedia
Contoh berikut mengurutkan baris berdasarkan bidang score secara descending. Jika suatu baris tidak berisi bidang tersebut, nilai score_backup yang digunakan. Jika kedua bidang tidak tersedia, baris tersebut ditempatkan di akhir.
FieldSort fieldSort = new FieldSort("score", SortOrder.DESC);
fieldSort.setMissingFields(Collections.singletonList("score_backup"));
fieldSort.setMissingValue(FieldSort.LAST_WHEN_MISSING);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(fieldSort)));
Mengurutkan bidang bernilai ganda dan Nested
Saat mengurutkan array atau bidang bernilai ganda lainnya, gunakan mode untuk menentukan nilai yang berpartisipasi dalam pengurutan. Contoh berikut mengurutkan baris secara descending berdasarkan nilai maksimum dalam array scores.
FieldSort fieldSort = new FieldSort("scores", SortOrder.DESC);
fieldSort.setMode(SortMode.MAX);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(fieldSort)));
Saat mengurutkan subfield Nested, konfigurasikan juga path Nested dan pilih baris anak yang berpartisipasi dalam pengurutan. Contoh berikut hanya menggunakan baris anak di mana items.age bernilai 1 dan mengurutkan baris secara ascending berdasarkan nilai minimum dari items.name.
TermQuery ageQuery = new TermQuery();
ageQuery.setFieldName("items.age");
ageQuery.setTerm(ColumnValue.fromLong(1));
FieldSort fieldSort = new FieldSort("items.name", SortOrder.ASC);
fieldSort.setMode(SortMode.MIN);
fieldSort.setNestedFilter(new NestedFilter("items", ageQuery));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(fieldSort)));
Mengurutkan berdasarkan jarak geografis
Contoh berikut mengembalikan baris dari terdekat ke terjauh berdasarkan jarak bola antara bidang location dan 30.23,120.19.
GeoDistanceSort geoSort = new GeoDistanceSort(
"location", Collections.singletonList("30.23,120.19"));
geoSort.setOrder(SortOrder.ASC);
geoSort.setDistanceType(GeoDistanceType.ARC);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(geoSort)));
Paginasi menggunakan limit dan offset
Contoh berikut melewati 100 baris pertama dan mengembalikan 100 baris berikutnya. Saat menggunakan metode ini, jumlah limit dan offset tidak boleh melebihi 100.000.
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(100);
searchQuery.setOffset(100);
Paginasi menggunakan token
Contoh berikut membaca semua hasil dalam loop. Token bernilai null untuk kueri pertama. Setiap kueri berikutnya langsung menggunakan nextToken dari respons sebelumnya. Setelah setToken dipanggil, SDK membersihkan sort karena token berisi kondisi pengurutan dari halaman sebelumnya.
List<Row> rows = new ArrayList<Row>();
byte[] nextToken = null;
do {
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(100);
searchQuery.setToken(nextToken);
SearchRequest request =
new SearchRequest("example_table", "example_index", searchQuery);
SearchResponse response = client.search(request);
rows.addAll(response.getRows());
nextToken = response.getNextToken();
} while (nextToken != null);
Offset tidak dapat dikonfigurasi dan halaman tidak dapat dilewati selama paginasi berbasis token. Untuk kembali ke halaman sebelumnya, simpan token yang digunakan untuk meminta setiap halaman dan lakukan kueri ulang menggunakan token untuk halaman target.
Indeks pencarian yang berisi bidang Nested tidak memiliki index sort. Untuk menggunakan paginasi berbasis token dengan jenis indeks ini, konfigurasikan sort secara eksplisit pada kueri pertama. Jika tidak, server tidak akan mengembalikan nextToken.
Untuk kueri berurutan dalam proses yang sama, teruskan nextToken langsung sebagai array byte. Gunakan encoding Base64 hanya ketika token harus disimpan atau ditransfer antar proses atau antara frontend dan backend. Jangan mengonversi token menggunakan new String(nextToken), karena akan merusak token.
String encodedToken = Base64.getEncoder().encodeToString(nextToken);
byte[] decodedToken = Base64.getDecoder().decode(encodedToken);