Ringkasan kueri

Halaman ini menjelaskan fungsi SEARCH dan mode kueri yang ditingkatkan, yang digunakan untuk menjalankan kueri penelusuran teks lengkap di tabel Spanner.

Membuat kueri indeks penelusuran

Spanner menyediakan fungsi SEARCH untuk digunakan untuk kueri indeks penelusuran. Contoh kasus penggunaan adalah aplikasi tempat pengguna memasukkan teks di kotak penelusuran dan aplikasi mengirim 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 mentah

Fungsi SEARCH hanya berfungsi jika indeks penelusuran ditentukan. Fungsi SEARCH dapat digabungkan dengan konstruksi SQL arbitrer, seperti filter, agregasi, atau join.

Fungsi SEARCH tidak dapat digunakan dengan kueri transaksi.

Kueri berikut menggunakan fungsi SEARCH untuk menampilkan semua album yang memiliki friday atau monday dalam judul:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')

Kueri penelusuran mentah dan bahasa rquery

Argumen kedua fungsi SEARCH adalah kueri penelusuran mentah. Spanner menggunakan bahasa khusus domain (DSL) yang disebut rquery.

Bahasa rquery mengikuti aturan yang sama dengan tokenizer teks biasa saat memisahkan string input menjadi istilah yang berbeda. Hal ini mencakup segmentasi bahasa Asia.

Untuk informasi tentang cara menggunakan rquery, lihat sintaksis rquery.

Mode kueri yang ditingkatkan

Spanner menawarkan dua mode penelusuran teks lengkap: penelusuran dasar berbasis token dan mode lanjutan 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.

SELECT AlbumId
FROM Albums
WHERE 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 algoritma peningkatan kueri. Akibatnya, kueri dengan enhance_query == true mungkin menghasilkan hasil yang sedikit berbeda dari waktu ke waktu.

Jika mode enhance_query diaktifkan, mode ini dapat meningkatkan jumlah istilah yang dicari fungsi SEARCH yang dapat sedikit meningkatkan latensi.

Misalnya, kueri berikut menggunakan waktu tunggu tiga detik dan gagal jika enhance_query tidak tersedia:

@{require_enhance_query=true, enhance_query_timeout_ms=3000}
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'fast car', enhance_query=>true)

Untuk informasi selengkapnya tentang cara menggunakan opsi enhance_query, lihat fungsi SEARCH.

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_SUBSTRING memerlukan indeks penelusuran. Spanner tidak mendukung fungsi ini dalam kueri terhadap tabel dasar atau indeks sekunder.

  • Indeks partisi harus memiliki semua kolom partisi yang terikat oleh kondisi kesetaraan dalam klausa WHERE kueri.

    Misalnya, jika indeks penelusuran ditentukan sebagai PARTITION BY x, y, kueri harus memiliki konjungsi dalam klausul WHERE dari x = <parameter or constant> AND y = <parameter or constant>. Indeks penelusuran tersebut tidak dipertimbangkan oleh pengoptimal kueri jika kondisi tersebut tidak ada.

  • Semua kolom TOKENLIST yang dirujuk oleh operator SEARCH dan SEARCH_SUBSTRING harus diindeks dalam indeks penelusuran yang sama.

    Misalnya, pertimbangkan tabel dan definisi indeks berikut:

    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);
    

    Kueri berikut gagal karena tidak ada satu indeks penelusuran yang mengindeks AlbumTitle_Tokens dan AlbumStudio_Tokens:

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)
    
  • Jika kolom urutan pengurutan bersifat nullable, skema dan kueri harus mengecualikan baris dengan kolom urutan pengurutan 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 di DML, DML yang dipartisi, atau kueri yang dipartisi.

  • Indeks penelusuran dan fungsi penelusuran biasanya digunakan dalam transaksi hanya baca. Jika persyaratan aplikasi mengizinkan hasil yang tidak berlaku, sebaiknya jalankan kueri penelusuran dengan durasi tidak berlaku 10 detik atau lebih. Untuk mengetahui informasi selengkapnya, lihat Membaca data yang tidak berlaku. Hal ini sangat berguna untuk kueri penelusuran besar yang menyebar ke beberapa grup Paxos.

    Indeks penelusuran dan fungsi penelusuran tidak direkomendasikan dalam transaksi baca-tulis. Selama eksekusi, kueri penelusuran mengunci seluruh partisi indeks; sebagai akibatnya, tingginya frekuensi kueri penelusuran dalam transaksi baca-tulis dapat menyebabkan konflik kunci yang menyebabkan lonjakan latensi. Secara default, indeks penelusuran tidak dipilih secara otomatis dalam transaksi baca-tulis. Jika kueri dipaksa untuk menggunakan indeks penelusuran dalam transaksi baca-tulis, kueri akan gagal secara default. Fungsi ini juga akan gagal jika kueri berisi salah satu fungsi penelusuran. Perilaku ini dapat diganti dengan petunjuk tingkat pernyataan @{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE} (tetapi kueri masih rentan terhadap konflik kunci).

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 tersebut tidak akan dipercepat dan tetap menjadi kondisi residual.

Parameter kueri

rquery dan parameter lainnya seperti OFFSET ditentukan sebagai literal atau parameter kueri. Sebaiknya gunakan parameter kueri untuk penelusuran teks lengkap, bukan literal string.

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, contoh berikut menunjukkan cara memaksa Spanner menggunakan AlbumsIndex:

SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE 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 potongan 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:

Daftar cuplikan

Membuat database menghasilkan cuplikan memiliki beberapa manfaat:

  1. Kemudahan: Anda tidak perlu menerapkan logika untuk membuat cuplikan dari kueri penelusuran.
  2. 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 ditandai atau dicetak tebal). Fungsi SNIPPET menghapus semua tag HTML dari string asli.

Misalnya, kode berikut menggunakan SNIPPET untuk mengambil teks dari AlbumTitle:

SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")

Langkah selanjutnya