Halaman ini menjelaskan fungsi SEARCH dan mode kueri yang ditingkatkan, yang digunakan untuk menjalankan kueri penelusuran teks lengkap pada tabel Spanner.
Membuat kueri indeks penelusuran
Spanner menyediakan fungsi SEARCH untuk digunakan dalam kueri indeks penelusuran. Contoh kasus penggunaan adalah aplikasi tempat pengguna memasukkan teks di
kotak penelusuran dan aplikasi mengirimkan input pengguna langsung ke fungsi
SEARCH. Fungsi SEARCH kemudian akan menggunakan indeks penelusuran untuk menemukan teks tersebut.
Fungsi SEARCH memerlukan dua argumen:
- Nama indeks penelusuran
- Kueri penelusuran
Fungsi SEARCH hanya berfungsi jika indeks penelusuran ditentukan. Fungsi SEARCH
dapat digabungkan dengan konstruksi SQL arbitrer, seperti filter,
agregasi, atau gabungan.
Fungsi SEARCH tidak dapat digunakan dengan kueri transaksi.
Kueri berikut menggunakan fungsi SEARCH untuk menampilkan semua album yang memiliki
friday atau monday dalam judul:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')
PostgreSQL
Contoh ini menggunakan spanner.search.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'friday OR monday')
Kueri penelusuran
Kueri penelusuran menggunakan sintaksis kueri penelusuran
mentah
secara default. Sintaksis alternatif dapat ditentukan menggunakan argumen SEARCH
dialect.
dialek rquery
Dialek defaultnya adalah raw search query. Spanner menggunakan bahasa khusus domain (DSL) yang disebut rquery.
Bahasa rquery mengikuti aturan yang sama dengan tokenizer teks biasa saat memisahkan kueri penelusuran input menjadi istilah yang berbeda. Hal ini mencakup segmentasi bahasa Asia.
Untuk mengetahui informasi tentang cara menggunakan rquery, lihat sintaksis rquery.
dialek kata
Kata dialect mirip dengan rquery, tetapi lebih sederhana. Tidak menggunakan operator
khusus. Misalnya, OR diperlakukan sebagai istilah penelusuran, bukan sebagai
operator disjungsi. Tanda kutip ganda ditangani sebagai tanda baca, bukan
penelusuran frasa, dan akan diabaikan.
Dengan kata dialect, AND diterapkan secara implisit ke semua istilah, dan diperlukan selama pencocokan. Tokenizer ini mengikuti aturan yang sama dengan tokenizer teks biasa
saat membagi kueri penelusuran input menjadi beberapa istilah.
Untuk mengetahui informasi tentang penggunaan dialek kata, lihat sintaksis kata.
dialek words_phrase
Dialek words_phrase tidak menggunakan operator khusus dan semua istilah diperlakukan sebagai frasa, yang berarti istilah harus berdekatan dan dalam urutan yang ditentukan.
Sama seperti rquery, dialek words_phrase mengikuti aturan yang sama dengan tokenizer teks biasa saat memisahkan kueri penelusuran input menjadi beberapa istilah.
Untuk mengetahui informasi tentang penggunaan dialek words_phrase, lihat sintaksis words phrase.
Mode kueri yang ditingkatkan
Spanner menawarkan dua mode penelusuran teks lengkap: penelusuran
berbasis token dasar dan mode yang lebih canggih yang disebut enhance_query. Jika diaktifkan,
enhance_query akan memperluas kueri penelusuran untuk menyertakan istilah dan sinonim terkait, sehingga meningkatkan kemungkinan menemukan hasil yang relevan.
Untuk mengaktifkan opsi ini, tetapkan argumen opsional enhance_query=>true dalam
fungsi SEARCH. Misalnya, kueri penelusuran hotl cal cocok dengan album
Hotel California.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)
PostgreSQL
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'hotl cal', enhance_query=>true)
Mode enhance_query adalah opsi waktu kueri. Hal ini tidak memengaruhi tokenisasi.
Anda dapat menggunakan indeks penelusuran yang sama dengan atau tanpa enhance_query.
Google terus meningkatkan kualitas algoritma peningkatan kueri. Akibatnya, kueri dengan enhance_query == true dapat memberikan hasil yang sedikit berbeda dari waktu ke waktu.
Jika mode enhance_query diaktifkan, jumlah istilah yang dicari oleh fungsi SEARCH dapat meningkat, sehingga latensi dapat sedikit meningkat.
Persyaratan kueri SQL
Ada beberapa kondisi yang harus dipenuhi kueri SQL untuk menggunakan indeks penelusuran. Jika kondisi ini tidak terpenuhi, kueri akan menggunakan rencana kueri alternatif atau gagal jika tidak ada rencana alternatif.
Kueri harus memenuhi kondisi berikut:
Fungsi SEARCH dan
SEARCH_SUBSTRINGmemerlukan indeks penelusuran. Spanner tidak mendukung fungsi ini dalam kueri terhadap tabel dasar atau indeks sekunder.Indeks yang dipartisi harus memiliki semua kolom partisi yang terikat oleh kondisi kesetaraan dalam klausul
WHEREkueri.Misalnya, jika indeks penelusuran ditentukan sebagai
PARTITION BY x, y, kueri harus memiliki konjungsi dalam klausulWHEREdarix = <parameter or constant> AND y = <parameter or constant>. Indeks penelusuran tersebut tidak dipertimbangkan oleh pengoptimal kueri jika kondisi tersebut tidak ada.Semua kolom
TOKENLISTyang dirujuk oleh operatorSEARCHdanSEARCH_SUBSTRINGharus diindeks dalam indeks penelusuran yang sama.Misalnya, pertimbangkan tabel dan definisi indeks berikut:
GoogleSQL
CREATE TABLE Albums ( AlbumId STRING(MAX) NOT NULL, AlbumTitle STRING(MAX), AlbumStudio STRING(MAX), AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN, AlbumStudio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumStudio)) HIDDEN ) PRIMARY KEY(AlbumId); CREATE SEARCH INDEX AlbumsTitleIndex ON Albums(AlbumTitle_Tokens); CREATE SEARCH INDEX AlbumsStudioIndex ON Albums(AlbumStudio_Tokens);PostgreSQL
CREATE TABLE albums ( albumid character varying NOT NULL, albumtitle character varying, albumstudio character varying, albumtitle_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN, albumstudio_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumstudio)) VIRTUAL HIDDEN, PRIMARY KEY(albumid)); CREATE SEARCH INDEX albumstitleindex ON albums(albumtitle_tokens); CREATE SEARCH INDEX albumsstudioindex ON albums(albumstudio_tokens);Kueri berikut gagal karena tidak ada satu indeks penelusuran yang mengindeks
AlbumTitle_TokensdanAlbumStudio_Tokens:GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)PostgreSQL
Contoh ini menggunakan parameter kueri
$1dan$2yang masing-masing terikat ke 'fast car' dan 'blue note'.SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, $1) AND spanner.search(albumstudio_tokens, $2)Jika kolom urutan pengurutan dapat bernilai null, skema dan kueri harus mengecualikan baris dengan kolom urutan pengurutan bernilai NULL. Untuk mengetahui detailnya, lihat Urutan pengurutan indeks penelusuran.
Jika indeks penelusuran difilter NULL, kueri harus menyertakan ekspresi pemfilteran NULL yang sama dengan yang digunakan dalam indeks. Lihat Indeks penelusuran yang difilter NULL untuk mengetahui detailnya.
Indeks penelusuran dan fungsi penelusuran tidak didukung dalam DML, DML berpartisi, atau kueri berpartisi.
Indeks penelusuran dan fungsi penelusuran biasanya digunakan dalam transaksi hanya baca. Jika persyaratan aplikasi mengizinkan hasil yang tidak terbaru, Anda mungkin dapat meningkatkan latensi dengan menjalankan kueri penelusuran dengan durasi tidak terbaru 10 detik atau lebih. Untuk mengetahui informasi selengkapnya, lihat Membaca data yang tidak berlaku. Hal ini sangat berguna untuk kueri penelusuran yang bercabang ke banyak pemisahan indeks.
Indeks penelusuran dan
fungsi penelusuran tidak
direkomendasikan dalam
transaksi baca-tulis.
Selama eksekusi, kueri penelusuran mengunci seluruh partisi indeks; akibatnya, tingkat kueri penelusuran yang tinggi dalam transaksi baca-tulis dapat menyebabkan konflik penguncian yang menyebabkan lonjakan latensi. Secara default, indeks penelusuran tidak dipilih secara otomatis dalam transaksi baca-tulis. Jika kueri dipaksa menggunakan
indeks penelusuran dalam transaksi baca-tulis, kueri akan gagal secara default. Kueri juga akan gagal jika berisi salah satu fungsi penelusuran. Perilaku ini dapat diganti
dengan petunjuk tingkat pernyataan @{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE}
GoogleSQL (tetapi kueri masih rentan terhadap konflik penguncian).
Setelah kondisi kelayakan indeks terpenuhi, pengoptimal kueri akan mencoba mempercepat kondisi kueri non-teks (seperti Rating > 4). Jika indeks penelusuran tidak menyertakan kolom TOKENLIST yang sesuai, kondisi tidak akan dipercepat dan tetap menjadi kondisi residual.
Parameter kueri
Argumen kueri penelusuran ditentukan sebagai literal atau parameter kueri. Sebaiknya gunakan parameter kueri untuk penelusuran teks lengkap, bukan string literal jika argumen mengizinkan nilai parameter kueri.
Pemilihan indeks
Spanner biasanya memilih indeks yang paling efisien untuk kueri
menggunakan pemodelan berbasis biaya. Namun, petunjuk FORCE_INDEX secara eksplisit menginstruksikan
Spanner untuk menggunakan indeks penelusuran tertentu. Misalnya, kode
berikut menunjukkan cara memaksa Spanner menggunakan AlbumsIndex:
GoogleSQL
SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
PostgreSQL
SELECT albumid
FROM albums/*@force_index=albumsindex*/
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
Jika indeks penelusuran yang ditentukan tidak memenuhi syarat, kueri akan gagal, meskipun ada indeks penelusuran lain yang memenuhi syarat.
Cuplikan di hasil penelusuran
Cuplikan adalah bagian teks yang diekstrak dari string tertentu yang memberi pengguna gambaran tentang isi hasil penelusuran, dan alasan hasil tersebut relevan dengan kueri mereka.
Misalnya, Gmail menggunakan cuplikan untuk menunjukkan bagian email yang cocok dengan kueri penelusuran:

Meminta database membuat cuplikan memiliki beberapa manfaat:
- Kemudahan: Anda tidak perlu menerapkan logika untuk membuat cuplikan dari kueri penelusuran.
- Efisiensi: Cuplikan mengurangi ukuran output dari server.
Fungsi SNIPPET
membuat cuplikan. Metode ini menampilkan bagian yang relevan dari nilai string asli beserta posisi karakter yang akan ditandai. Klien kemudian dapat memilih cara menampilkan cuplikan kepada pengguna akhir (misalnya, menggunakan teks yang dicetak tebal atau disorot).
Misalnya, kode berikut menggunakan SNIPPET untuk mengambil teks dari AlbumTitle:
GoogleSQL
SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")
PostgreSQL
Contoh ini menggunakan spanner.snippet.
SELECT albumid, spanner.snippet(albumtitle, 'Fast Car')
FROM albums
WHERE spanner.search(albumtitle_tokens, 'Fast Car')
Langkah berikutnya
- Pelajari cara mengurutkan hasil penelusuran.
- Pelajari cara melakukan penelusuran substring.
- Pelajari cara memberi nomor halaman pada hasil penelusuran.
- Pelajari cara mencampur kueri teks lengkap dan non-teks.
- Pelajari cara menelusuri beberapa kolom.