Halaman ini menjelaskan cara menyambungkan TOKENLIST
di
indeks penelusuran saat Anda menyiapkan skema
atau dalam kueri penelusuran saat melakukan penelusuran teks lengkap di Spanner.
Menggabungkan TOKENLIST dalam indeks penelusuran
Terkadang, Anda memerlukan aplikasi untuk menelusuri setiap kolom. Terkadang, aplikasi perlu menelusuri semua kolom. Misalnya, dalam tabel dengan dua kolom string, Anda mungkin ingin aplikasi menelusuri kedua kolom tanpa membedakan kolom mana yang berisi pencocokan.
Di Spanner, ada dua cara untuk melakukannya:
- Buat token kata secara terpisah dan gabungkan
TOKENLIST
yang dihasilkan (direkomendasikan). - Gabungkan string dan tokenkan hasilnya.
Dengan pendekatan kedua, ada dua masalah:
- Jika Anda ingin mengindeks
Title
atauStudio
satu per satu, selain mengindeksnya dalamTOKENLIST
gabungan, teks yang sama akan ditokenisasi dua kali. Hal ini menyebabkan transaksi menggunakan lebih banyak resource. - Penelusuran frasa mencakup kedua kolom. Misalnya, jika
@p
ditetapkan ke"Blue Note"
, nilai ini akan cocok dengan baris yang berisiTitle
="Big Blue Note" danStudio
="Blue Note Studios".
Pendekatan pertama menyelesaikan masalah ini karena frasa hanya cocok dengan satu kolom
dan setiap kolom string hanya ditokenisasi satu kali jika TOKENLIST
individual dan gabungan
diindeks. Meskipun setiap kolom string hanya ditokenisasi satu kali,
TOKENLIST
yang dihasilkan disimpan secara terpisah dalam indeks.
Membuat token kata secara terpisah dan menggabungkan TOKENLIST
Contoh berikut membuat token setiap kata dan menggunakan
TOKENLIST_CONCAT
untuk menyambungkan TOKENLIST
:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Title STRING(MAX),
Studio STRING(MAX),
Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
Combined_Tokens TOKENLIST AS (TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens])) HIDDEN,
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);
SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);
PostgreSQL
PostgreSQL menggunakan
spanner.tokenlist_concat
untuk penyambungan. Parameter kueri $1
terikat dengan 'Hatel Kaliphorn'.
CREATE TABLE albums (
albumid character varying NOT NULL,
title character varying,
studio character varying,
title_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(title)) VIRTUAL HIDDEN,
studio_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(studio)) VIRTUAL HIDDEN,
combined_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenlist_concat(ARRAY[spanner.tokenize_fulltext(title), spanner.tokenize_fulltext(studio)])) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex ON albums(combined_tokens);
SELECT albumid FROM albums WHERE spanner.search(combined_tokens, $1);
Perhatikan bahwa tokenlist_concat
tidak memanggil title_tokens
atau studio_tokens
,
tetapi memanggil spanner.tokenize_fulltext(title)
dan
spanner.tokenize_fulltext(studio)
. Hal ini karena PostgreSQL
tidak mendukung referensi kolom yang dihasilkan yang berada dalam kolom
yang dihasilkan lainnya. spanner.tokenlist_concat
perlu memanggil fungsi tokenisasi dan tidak
mereferensikan kolom tokenlist secara langsung.
Penggabungan TOKENLIST
juga dapat diterapkan sepenuhnya di sisi kueri.
Untuk mengetahui informasi selengkapnya, lihat Penggabungan TOKENLIST
sisi kueri.
TOKENLIST_CONCAT
didukung untuk penelusuran teks lengkap dan
substring.
Spanner tidak mengizinkan Anda menggabungkan jenis tokenisasi, seperti
TOKENIZE_FULLTEXT
dan TOKENIZE_SUBSTRING
dalam panggilan TOKENLIST_CONCAT
yang sama.
Di GoogleSQL, definisi kolom TOKENLIST
teks dapat
diubah di kolom yang tidak disimpan untuk menambahkan kolom tambahan. Hal ini berguna saat Anda
ingin menambahkan kolom tambahan ke TOKENLIST_CONCAT
. Mengubah ekspresi kolom yang dihasilkan tidak akan mengisi ulang baris yang ada dalam indeks.
Menggabungkan string dan membuat token hasil
Contoh berikut menyambungkan string dan membuat token hasil:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Title STRING(MAX),
Studio STRING(MAX),
Combined_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title || " " || Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);
SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
title character varying,
studio character varying,
combined_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(title || ' ' || studio)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex ON albums(combined_tokens);
SELECT albumid FROM albums WHERE spanner.search(combined_tokens, $1);
Penggabungan TOKENLIST
sisi kueri
Kompromi dengan pengindeksan TOKENLIST
yang digabungkan adalah peningkatan biaya penyimpanan dan operasi tulis. Setiap token kini disimpan di disk dua kali:
sekali dalam daftar postingan TOKENLIST
aslinya, dan sekali dalam daftar postingan
TOKENLIST
gabungan. Penggabungan sisi kueri kolom TOKENLIST
menghindari biaya ini, tetapi kueri menggunakan lebih banyak resource komputasi.
Untuk menyambungkan beberapa TOKENLIST
, gunakan fungsi TOKENLIST_CONCAT
dalam kueri SEARCH
. Untuk bagian ini, kita menggunakan contoh skema berikut:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Title STRING(MAX),
Studio STRING(MAX),
Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex ON Albums(Title_Tokens, Studio_Tokens);
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
title character varying,
studio character varying,
title_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(title)) VIRTUAL HIDDEN,
studio_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(studio)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex ON albums(title_tokens, studio_tokens);
Kueri berikut menelusuri baris yang memiliki token "blue"
dan "note" di mana saja di kolom Title
dan Studio
. Hal ini mencakup
baris dengan "biru" dan "catatan" di kolom Title
, "biru" dan "catatan" di
kolom Studio
, dan "biru" di kolom Title
dan "catatan" di kolom Studio
, atau sebaliknya.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')
PostgreSQL
Contoh ini menggunakan
spanner.search
dengan
spanner.tokenlist_concat
.
SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[albumtitle_tokens, studio_tokens]), 'blue note')
Penggabungan TOKENLIST
sisi tulis dan sisi kueri menghasilkan hasil yang identik.
Pilihan antara keduanya adalah kompromi antara biaya disk dan biaya kueri.
Atau, aplikasi dapat menelusuri beberapa kolom TOKENLIST
dan menggunakan
OR
bersama dengan fungsi SEARCH
:
GoogleSQL
SEARCH(AlbumTitle_Tokens, 'Blue Note') OR SEARCH(Studio_Tokens, 'Blue Note')
PostgreSQL
spanner.search(albumtitle_tokens, 'Blue Note') OR spanner.search(studio_tokens, 'Blue Note')
Namun, hal ini memiliki semantik yang berbeda. Tidak cocok dengan album yang
AlbumTitle_Tokens
-nya memiliki "biru", tetapi tidak memiliki "catatan" dan Studio_Tokens
-nya memiliki
"catatan", tetapi tidak memiliki "biru".
Langkah berikutnya
- Pelajari kueri penelusuran teks lengkap.
- Pelajari indeks penelusuran.