Anda dapat melakukan kueri bersarang untuk mengakses data pada baris anak dari bidang bersarang. Bidang bersarang tidak dapat di-kueri secara langsung. Untuk menanyakan bidang bersarang, tentukan jalur bidang bersarang dan subkueri dalam objek NestedQuery. Subkueri dapat berupa kueri dari jenis apa pun.
Prasyarat
Klien Tablestore telah diinisialisasi. Untuk informasi lebih lanjut, lihat Inisialisasi klien Tablestore.
Tabel data telah dibuat dan data telah ditulis ke tabel. Untuk informasi lebih lanjut, lihat Buat tabel data dan Tulis data.
Indeks pencarian telah dibuat untuk tabel data. Untuk informasi lebih lanjut, lihat Buat indeks pencarian.
Parameter
Parameter | Deskripsi |
path | Jalur bidang bersarang. Jalur ini mirip dengan struktur pohon. Sebagai contoh, news.title menunjukkan subbidang judul dalam bidang bersarang bernama news. |
query | Kueri yang ingin Anda lakukan pada subbidang dalam bidang bersarang. Kueri dapat berupa jenis kueri apa pun. |
scoreMode | Nilai yang digunakan untuk menghitung skor ketika sebuah bidang berisi beberapa nilai. |
getTotalCount | Menentukan apakah akan mengembalikan jumlah total baris yang memenuhi kondisi kueri. Nilai default parameter ini adalah false, yang menentukan bahwa jumlah total baris yang memenuhi kondisi kueri tidak dikembalikan. Jika Anda mengatur parameter ini ke true, kinerja kueri akan terpengaruh. |
weight | Bobot yang ingin Anda tetapkan pada bidang yang ingin Anda kueri untuk menghitung skor relevansi kata kunci berbasis BM25. Parameter ini digunakan dalam skenario pencarian teks lengkap. Jika Anda menentukan bobot yang lebih tinggi untuk bidang yang ingin Anda kueri, skor relevansi kata kunci berbasis BM25 untuk bidang tersebut akan lebih tinggi. Nilai parameter ini adalah bilangan titik mengambang positif. Parameter ini tidak memengaruhi jumlah baris yang dikembalikan. Namun, parameter ini memengaruhi skor relevansi kata kunci berbasis BM25 dari hasil kueri. |
tableName | Nama tabel data. |
indexName | Nama indeks pencarian. |
columnsToGet | Menentukan apakah akan mengembalikan semua kolom setiap baris yang memenuhi kondisi kueri. Anda dapat mengonfigurasi parameter returnAll dan columns untuk parameter ini. Nilai default parameter returnAll adalah false, yang menentukan bahwa tidak semua kolom dikembalikan. Dalam hal ini, Anda dapat menggunakan parameter columns untuk menentukan kolom yang ingin Anda kembalikan. Jika Anda tidak menentukan kolom yang ingin Anda kembalikan, hanya kolom kunci utama yang dikembalikan. Jika Anda mengatur parameter returnAll ke true, semua kolom dikembalikan. |
InnerHits | Pengaturan subbidang dari bidang bersarang.
|
Contoh
Contoh berikut menunjukkan cara melakukan kueri bersarang.
Kueri bidang bersarang satu level
Kode sampel berikut memberikan contoh tentang cara menanyakan baris di mana nilai kolom col_nested.nested_1 adalah "tablestore". Dalam contoh ini, kolom bersarang bernama col_nested mencakup subkolom nested_1 dan nested_2.
private static void nestedQuery(SyncClient client) {
SearchQuery searchQuery = new SearchQuery();
NestedQuery nestedQuery = new NestedQuery(); // Atur jenis kueri ke NestedQuery.
nestedQuery.setPath("col_nested"); // Tentukan jalur kolom bersarang.
TermQuery termQuery = new TermQuery(); // Tentukan subkueri untuk melakukan kueri bersarang.
termQuery.setFieldName("col_nested.nested_1"); // Tentukan nama kolom. Nama tersebut harus mencakup jalur kolom bersarang.
termQuery.setTerm(ColumnValue.fromString("tablestore")); // Tentukan nilai yang ingin Anda gunakan untuk mencocokkan nilai kolom.
nestedQuery.setQuery(termQuery);
nestedQuery.setScoreMode(ScoreMode.None);
searchQuery.setQuery(nestedQuery);
//searchQuery.setGetTotalCount(true);// Atur parameter GetTotalCount ke true untuk mengembalikan jumlah total baris yang cocok.
SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
// Anda dapat mengonfigurasi parameter columnsToGet untuk menentukan kolom yang akan dikembalikan atau menentukan bahwa semua kolom dikembalikan. Jika Anda tidak mengonfigurasi parameter ini, hanya kolom kunci utama yang dikembalikan.
//SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
//columnsToGet.setReturnAll(true); // Tentukan bahwa semua kolom dikembalikan.
//columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); // Tentukan kolom yang ingin Anda kembalikan.
//searchRequest.setColumnsToGet(columnsToGet);
SearchResponse resp = client.search(searchRequest);
//System.out.println("TotalCount: " + resp.getTotalCount()); // Tentukan bahwa jumlah total baris yang cocok bukan jumlah baris yang dikembalikan.
System.out.println("Row: " + resp.getRows());
}Kueri bidang bersarang multi-level
Kode sampel berikut memberikan contoh tentang cara menanyakan baris di mana nilai kolom col_nested.nested_2.nested_2_2 adalah "tablestore". Dalam contoh ini, kolom bersarang bernama col_nested mencakup subkolom nested_1 dan nested_2. Subkolom nested_2 mencakup kolom nested_2_1 dan nested_2_2.
private static void nestedQuery(SyncClient client) {
SearchQuery searchQuery = new SearchQuery();
NestedQuery nestedQuery = new NestedQuery(); // Atur jenis kueri ke NestedQuery.
nestedQuery.setPath("col_nested.nested_2"); // Tentukan jalur kolom bersarang, yaitu jalur induk kolom yang ingin Anda kueri.
TermQuery termQuery = new TermQuery(); // Tentukan subkueri untuk melakukan kueri bersarang.
termQuery.setFieldName("col_nested.nested_2.nested_2_2"); // Tentukan nama kolom. Nama tersebut harus mencakup jalur kolom bersarang.
termQuery.setTerm(ColumnValue.fromString("tablestore")); // Tentukan nilai yang ingin Anda gunakan untuk mencocokkan nilai kolom.
nestedQuery.setQuery(termQuery);
nestedQuery.setScoreMode(ScoreMode.None);
searchQuery.setQuery(nestedQuery);
//searchQuery.setGetTotalCount(true);// Atur parameter GetTotalCount ke true untuk mengembalikan jumlah total baris yang cocok.
SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
// Anda dapat mengonfigurasi parameter columnsToGet untuk menentukan kolom yang akan dikembalikan atau menentukan bahwa semua kolom dikembalikan. Jika Anda tidak mengonfigurasi parameter ini, hanya kolom kunci utama yang dikembalikan.
//SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
//columnsToGet.setReturnAll(true); // Tentukan bahwa semua kolom dikembalikan.
//columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); // Tentukan kolom yang ingin Anda kembalikan.
//searchRequest.setColumnsToGet(columnsToGet);
SearchResponse resp = client.search(searchRequest);
//System.out.println("TotalCount: " + resp.getTotalCount()); // Tentukan bahwa jumlah total baris yang cocok bukan jumlah baris yang dikembalikan.
System.out.println("Row: " + resp.getRows());
}Menggabungkan kueri bersarang dengan kueri Boolean
Persyaratan kueri
Kode sampel berikut memberikan contoh tentang cara menanyakan data berdasarkan persyaratan kueri Anda. Lihat kode sampel yang sesuai berdasarkan persyaratan kueri Anda.
Baris anak yang sama memenuhi beberapa kondisi kueri
Kode sampel berikut memberikan contoh tentang cara menanyakan baris di mana nilai kolom col_nested.col_keyword adalah "tablestore" dan nilai kolom col_nested.col_long tidak kosong. Kolom col_nested.col_keyword dan col_nested.col_long termasuk dalam baris anak yang sama.
Berdasarkan baris sampel dalam tabel data, hanya baris dengan nomor seri 2 yang memenuhi kondisi kueri.
public static void nestedQuery(SyncClient client) {
// Kondisi kueri 1: Nilai kolom col_keyword dalam baris anak kolom col_nested adalah "tablestore".
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("col_nested.col_keyword");
termQuery.setTerm(ColumnValue.fromString("tablestore"));
// Kondisi kueri 2: Nilai kolom col_long dalam baris anak kolom col_nested tidak kosong.
ExistsQuery existsQuery = new ExistsQuery();
existsQuery.setFieldName("col_nested.col_long");
// Gunakan operator And dari kueri Boolean untuk menanyakan baris-baris yang memenuhi dua kondisi kueri sebelumnya pada saat yang sama.
List<Query> mustQueries = new ArrayList<>();
mustQueries.add(termQuery);
mustQueries.add(existsQuery);
BoolQuery boolQuery = new BoolQuery();
boolQuery.setMustQueries(mustQueries);
// Tentukan beberapa kueri Boolean dalam kueri bersarang untuk menanyakan baris-baris yang memenuhi dua kondisi kueri sebelumnya pada saat yang sama.
NestedQuery nestedQuery = new NestedQuery(); // Atur jenis kueri ke NestedQuery.
nestedQuery.setPath("col_nested"); // Tentukan jalur kolom bersarang, yaitu jalur induk kolom yang ingin Anda kueri.
nestedQuery.setQuery(boolQuery);
nestedQuery.setScoreMode(ScoreMode.None);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(nestedQuery);
SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
// Anda dapat mengonfigurasi parameter columnsToGet untuk menentukan kolom yang akan dikembalikan atau menentukan bahwa semua kolom dikembalikan. Jika Anda tidak mengonfigurasi parameter ini, hanya kolom kunci utama yang dikembalikan.
//SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
//columnsToGet.setReturnAll(true); // Tentukan bahwa semua kolom dikembalikan.
//columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); // Tentukan kolom yang ingin Anda kembalikan.
//searchRequest.setColumnsToGet(columnsToGet);
SearchResponse resp = client.search(searchRequest);
//System.out.println("TotalCount: " + resp.getTotalCount()); // Tentukan bahwa jumlah total baris yang cocok bukan jumlah baris yang dikembalikan.
System.out.println("Row: " + resp.getRows());
}Baris anak yang berbeda memenuhi beberapa kondisi kueri
Kode sampel berikut memberikan contoh tentang cara menanyakan baris di mana nilai kolom col_nested.col_keyword adalah "tablestore" dan nilai kolom col_nested.col_long tidak kosong. Kolom col_nested.col_keyword dan col_nested.col_long termasuk dalam baris anak yang sama atau berbeda.
Berdasarkan baris sampel dalam tabel data, baris dengan nomor seri 1 dan 2 memenuhi kondisi kueri.
public static void nestedQuery(SyncClient client) {
// Kondisi kueri 1: Nilai kolom col_keyword dalam baris anak kolom col_nested adalah "tablestore".
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("col_nested.col_keyword");
termQuery.setTerm(ColumnValue.fromString("tablestore"));
NestedQuery nestedTermQuery = new NestedQuery();
nestedTermQuery.setPath("col_nested");
nestedTermQuery.setScoreMode(ScoreMode.None);
nestedTermQuery.setQuery(termQuery);
// Kondisi kueri 2: Nilai kolom col_long dalam baris anak kolom col_nested tidak kosong.
ExistsQuery existsQuery = new ExistsQuery();
existsQuery.setFieldName("col_nested.col_long");
NestedQuery nestedExistsQuery = new NestedQuery();
nestedExistsQuery.setPath("col_nested");
nestedExistsQuery.setScoreMode(ScoreMode.None);
nestedExistsQuery.setQuery(existsQuery);
// Gunakan operator And dari kueri Boolean untuk menanyakan baris-baris yang memenuhi dua kondisi kueri sebelumnya.
List<Query> mustQueries = new ArrayList<>();
mustQueries.add(nestedTermQuery);
mustQueries.add(nestedExistsQuery);
// Tentukan beberapa kueri bersarang dalam kueri Boolean untuk menanyakan baris-baris yang memenuhi kondisi kueri.
BoolQuery boolQuery = new BoolQuery();
boolQuery.setMustQueries(mustQueries);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(boolQuery);
SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
// Anda dapat mengonfigurasi parameter columnsToGet untuk menentukan kolom yang akan dikembalikan atau menentukan bahwa semua kolom dikembalikan. Jika Anda tidak mengonfigurasi parameter ini, hanya kolom kunci utama yang dikembalikan.
//SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
//columnsToGet.setReturnAll(true); // Tentukan bahwa semua kolom dikembalikan.
//columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); // Tentukan kolom yang ingin Anda kembalikan.
//searchRequest.setColumnsToGet(columnsToGet);
SearchResponse resp = client.search(searchRequest);
//System.out.println("TotalCount: " + resp.getTotalCount()); // Tentukan bahwa jumlah total baris yang cocok bukan jumlah baris yang dikembalikan.
System.out.println("Row: " + resp.getRows());
}Gunakan fitur sorotan dalam kueri bersarang
Kode sampel berikut memberikan contoh tentang cara menggunakan kueri bersarang untuk menanyakan baris di mana nilai subkolom Level1_Col1_Nested dari kolom bersarang bernama Col_Nested cocok dengan hangzhou shanghai dan menyoroti string kueri dalam hasil kueri.
/**
* Aktifkan fitur sorotan dengan menggunakan parameter innerHits untuk kueri bersarang.
*/
public static void nestedQueryWithHighlighting(SyncClient client) {
SearchRequest searchRequest = SearchRequest.newBuilder()
.tableName("<TABLE_NAME>")
.indexName("<SEARCH_INDEX_NAME>")
.returnAllColumnsFromIndex(true)
.searchQuery(SearchQuery.newBuilder()
.limit(5)
.query(QueryBuilders.nested()
.path("Col_Nested")
.scoreMode(ScoreMode.Min)
.query(QueryBuilders.match("Col_Nested.Level1_Col1_Nested", "hangzhou shanghai"))
.innerHits(InnerHits.newBuilder()
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Nested.Level1_Col1_Nested", HighlightParameter.newBuilder().build())
.build())
.build()))
.build())
.build();
SearchResponse resp = client.search(searchRequest);
// Tampilkan hasil yang disorot.
printSearchHit(resp.getSearchHits(), "");
}
/**
* Tampilkan konten yang memenuhi kondisi kueri.
* @param searchHits searchHits
* Jika output menggunakan @param prefix Struktur Bersarang, tambahkan awalan untuk menampilkan informasi hierarki.
*/
private static void printSearchHit(List<SearchHit> searchHits, String prefix) {
for (SearchHit searchHit : searchHits) {
if (searchHit.getScore() != null) {
System.out.printf("%s Skor: %s\n", prefix, searchHit.getScore());
}
if (searchHit.getOffset() != null) {
System.out.printf("%s Offset: %s\n", prefix, searchHit.getOffset());
}
if (searchHit.getRow() != null) {
System.out.printf("%s Baris: %s\n", prefix, searchHit.getRow().toString());
}
// Tampilkan segmen teks yang disorot dari kolom dalam setiap baris.
if (searchHit.getHighlightResultItem() != null) {
System.out.printf("%s Sorotan: \n", prefix);
StringBuilder strBuilder = new StringBuilder();
for (Map.Entry<String, HighlightField> entry : searchHit.getHighlightResultItem().getHighlightFields().entrySet()) {
strBuilder.append(entry.getKey()).append(":").append("[");
strBuilder.append(StringUtils.join(",", entry.getValue().getFragments())).append("]\n");
}
System.out.printf("%s %s", prefix, strBuilder);
}
// Hasil sorotan dari kolom bersarang.
for (SearchInnerHit searchInnerHit : searchHit.getSearchInnerHits().values()) {
System.out.printf("%s Jalur: %s\n", prefix, searchInnerHit.getPath());
System.out.printf("%s InnerHit: \n", prefix);
printSearchHit(searchInnerHit.getSubSearchHits(), prefix + " ");
}
System.out.println();
}
}Sebagai contoh, bidang Col_Nested terdiri dari subbidang berikut: subbidang Level1_Col1_Text tipe Text dan subbidang Level1_Col2_Nested tipe Nested. Subbidang Level1_Col2_Nested tipe Nested juga terdiri dari bidang Level2_Col1_Text.
Kode sampel berikut memberikan contoh tentang cara menambahkan kueri Boolean ke kueri bersarang untuk menyoroti string kueri dalam bidang Level1_Col1_Text dan subbidang Level2_Col1_Text dari bidang Level1_Col2_Nested.
public static void nestedQueryWithHighlighting(SyncClient client) {
SearchRequest searchRequest = SearchRequest.newBuilder()
.tableName("<TABLE_NAME>")
.indexName("<SEARCH_INDEX_NAME>")
.returnAllColumnsFromIndex(true)
.searchQuery(SearchQuery.newBuilder()
.limit(5)
.query(QueryBuilders.nested()
.path("Col_Nested")
.scoreMode(ScoreMode.Min)
.query(QueryBuilders.bool()
.should(QueryBuilders.match("Col_Nested.Level1_Col1_Text", "hangzhou shanghai"))
.should(QueryBuilders.nested()
.path("Col_Nested.Level1_Col2_Nested")
.scoreMode(ScoreMode.Min)
.query(QueryBuilders.match("Col_Nested.Level1_Col2_Nested.Level2_Col1_Text", "hangzhou shanghai"))
.innerHits(InnerHits.newBuilder()
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Nested.Level1_Col2_Nested.Level2_Col1_Text", HighlightParame
.build())
.build())))
.innerHits(InnerHits.newBuilder()
.sort(new Sort(Arrays.asList(
new ScoreSort(),
new DocSort()
)))
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Nested.Level1_Col1_Text", HighlightParameter.newBuilder().build())
.build())
.build()))
.build())
.build();
SearchResponse resp = client.search(searchRequest);
// Tampilkan hasil yang disorot.
printSearchHit(resp.getSearchHits(), "");
}
/**
* Tampilkan konten yang memenuhi kondisi kueri.
* @param searchHits searchHits
* Jika output menggunakan @param prefix Struktur Bersarang, tambahkan awalan untuk menampilkan informasi hierarki.
*/
private static void printSearchHit(List<SearchHit> searchHits, String prefix) {
for (SearchHit searchHit : searchHits) {
if (searchHit.getScore() != null) {
System.out.printf("%s Skor: %s\n", prefix, searchHit.getScore());
}
if (searchHit.getOffset() != null) {
System.out.printf("%s Offset: %s\n", prefix, searchHit.getOffset());
}
if (searchHit.getRow() != null) {
System.out.printf("%s Baris: %s\n", prefix, searchHit.getRow().toString());
}
// Tampilkan segmen teks yang disorot dari bidang dalam setiap baris.
if (searchHit.getHighlightResultItem() != null) {
System.out.printf("%s Sorotan: \n", prefix);
StringBuilder strBuilder = new StringBuilder();
for (Map.Entry<String, HighlightField> entry : searchHit.getHighlightResultItem().getHighlightFields().entrySet()) {
strBuilder.append(entry.getKey()).append(":").append("[");
strBuilder.append(StringUtils.join(",", entry.getValue().getFragments())).append("]\n");
}
System.out.printf("%s %s", prefix, strBuilder);
}
// Hasil sorotan dari kolom bersarang.
for (SearchInnerHit searchInnerHit : searchHit.getSearchInnerHits().values()) {
System.out.printf("%s Jalur: %s\n", prefix, searchInnerHit.getPath());
System.out.printf("%s InnerHit: \n", prefix);
printSearchHit(searchInnerHit.getSubSearchHits(), prefix + " ");
}
System.out.println();
}
}
FAQ
Referensi
Saat Anda menggunakan indeks pencarian untuk menanyakan data, Anda dapat menggunakan metode kueri berikut: kueri tepat, kueri multi-tepat, kueri cocok semua, kueri cocok, kueri frasa cocok, kueri awalan, kueri rentang, kueri wildcard, kueri geo, kueri vektor KNN, kueri Boolean, kueri bersarang, dan kueri eksis. Setelah Anda membuat indeks pencarian, Anda dapat menggunakan metode kueri yang disediakan oleh indeks pencarian untuk menanyakan data dari berbagai dimensi berdasarkan kebutuhan bisnis Anda.
Anda dapat mengurutkan atau membagi halaman baris yang memenuhi kondisi kueri dengan menggunakan fitur pengurutan dan pemisahan halaman. Untuk informasi lebih lanjut, lihat Lakukan pengurutan dan pemisahan halaman.
Anda dapat menggunakan fitur collapse (distinct) untuk merangkum set hasil berdasarkan kolom tertentu. Dengan cara ini, data tipe tertentu hanya muncul sekali dalam hasil kueri. Untuk informasi lebih lanjut, lihat Collapse (distinct).
Jika Anda ingin menganalisis data dalam tabel, Anda dapat memanggil operasi Search untuk menggunakan fitur agregasi atau menggunakan fitur kueri SQL. Sebagai contoh, Anda dapat menanyakan nilai maksimum dan minimum, jumlah nilai, dan jumlah baris. Untuk informasi lebih lanjut, lihat Agregasi dan Kueri SQL.
Jika Anda ingin mendapatkan semua baris yang memenuhi kondisi kueri tanpa perlu mengurutkan baris, Anda dapat memanggil operasi ParallelScan dan ComputeSplits untuk menggunakan fitur pemindaian paralel. Untuk informasi lebih lanjut, lihat Pemindaian paralel.