Tokenisasi

Halaman ini menjelaskan cara menambahkan tokenisasi ke tabel. Tokenisasi diperlukan untuk membuat token yang digunakan dalam indeks penelusuran.

Tokenisasi adalah proses mengubah nilai menjadi token. Metode yang Anda gunakan untuk melakukan tokenisasi dokumen menentukan jenis dan efisiensi penelusuran yang dapat dilakukan pengguna di dalamnya.

Spanner menyediakan tokenizer untuk teks bahasa alami, substring, teks verbatim, angka, dan boolean. Skema database menggunakan tokenizer yang cocok dengan jenis penelusuran yang diperlukan untuk kolom. Tokenizer memiliki karakteristik berikut:

  • Setiap tokenizer adalah fungsi SQL yang mendapatkan input, seperti string atau angka, dan argumen bernama untuk opsi tambahan.
  • Tokenizer menghasilkan TOKENLIST.

Misalnya, string teks The quick brown fox jumps over the lazy dog ditokenisasi menjadi [the,quick,brown,fox,jumps,over,the,lazy,dog]. String HTML The <b>apple</b> is <i>red</i> di-tokenisasi menjadi [the,apple,is,red].

Token memiliki karakteristik berikut:

  • Token disimpan dalam kolom yang menggunakan jenis data TOKENLIST.
  • Setiap token disimpan sebagai urutan byte, dengan kumpulan atribut terkait opsional. Misalnya, dalam aplikasi teks lengkap, token biasanya berupa satu kata dari dokumen tekstual.
  • Saat melakukan tokenisasi nilai HTML, Spanner menghasilkan atribut yang menunjukkan keunggulan token dalam dokumen. Spanner menggunakan atribut ini untuk penskoran guna meningkatkan istilah yang lebih penting (seperti judul).

Tokenizer

Spanner mendukung fungsi tokenizer berikut:

  • Tokenizer teks lengkap (TOKENIZE_FULLTEXT) menghasilkan token kata utuh untuk kueri bahasa alami.

    Contoh

    Kedua fungsi berikut

    GoogleSQL

    TOKENIZE_FULLTEXT("Yellow apple")
    TOKENIZE_FULLTEXT("Yellow <b>apple</b>", content_type=>"text/html")
    

    PostgreSQL

    Contoh ini menggunakan spanner.tokenize_fulltext.

    spanner.tokenize_fulltext("Yellow apple")
    spanner.tokenize_fulltext('Yellow <b>apple</b>', context_type=>'text/html')
    

    menghasilkan token yang sama: [yellow,apple].

  • Tokenizer substring (TOKENIZE_SUBSTRING) menghasilkan token untuk setiap n-gram dari setiap kata. Fungsi ini digunakan untuk menemukan substring kata dalam teks.

    Contoh

    GoogleSQL

    TOKENIZE_SUBSTRING('hello world', ngram_size_min=>4, ngram_size_max=>6)
    

    PostgreSQL

    Contoh ini menggunakan spanner.tokenize_substring.

    spanner.tokenize_substring('hello world', ngram_size_min=>4, ngram_size_max=>6)
    

    Menghasilkan token berikut: [ello,hell,hello,orld,worl,world].

  • Pengubah token n-gram (TOKENIZE_NGRAMS) menghasilkan n-gram dari input (tanpa membaginya menjadi kata-kata terpisah). Indeks ini digunakan untuk mempercepat predikat ekspresi reguler.

    Contoh

    Fungsi berikut:

    GoogleSQL

    TOKENIZE_NGRAMS("Big Time", ngram_size_min=>4, ngram_size_max=>4)
    

    PostgreSQL

    Contoh ini menggunakan spanner.tokenize_ngrams.

    spanner.tokenize_ngrams('big time', ngram_size_min=>4, ngram_size_max=>4)
    

    Menghasilkan token berikut: ["Big ","ig T","g Ti"," Tim", "Time"].

  • Tokenizer pencocokan persis (TOKEN dan TOKENIZE_BOOL) digunakan untuk mencari baris yang berisi nilai tertentu di salah satu kolomnya. Misalnya, aplikasi yang mengindeks katalog produk mungkin ingin menelusuri produk dari merek dan warna tertentu.

    Contoh

    Fungsi berikut:

    GoogleSQL

    TOKEN("hello")
    TOKEN(["hello", "world"])
    

    PostgreSQL

    Contoh ini menggunakan spanner.token.

    spanner.token('hello')
    

    Menghasilkan token berikut: [hello].

    Fungsi berikut:

    GoogleSQL

    TOKENIZE_BOOL(true)
    

    PostgreSQL

    Contoh ini menggunakan spanner.tokenize_bool.

    spanner.tokenize_bool(true)
    

    Menghasilkan token berikut: [y].

  • Tokenizer angka (TOKENIZE_NUMBER) digunakan untuk menghasilkan serangkaian token yang mempercepat penelusuran perbandingan numerik. Untuk kondisi kesetaraan, tokennya adalah angka itu sendiri. Untuk kondisi rentang (seperti rating >= 3.5), kumpulan token lebih rumit.

    Contoh

    Pernyataan fungsi berikut:

    GoogleSQL

    TOKENIZE_NUMBER(42, comparison_type=>'equality')
    TOKENIZE_NUMBER(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)
    

    PostgreSQL

    Contoh ini menggunakan spanner.tokenize_number.

    spanner.tokenize_number(42, comparison_type=>'equality')
    spanner.tokenize_number(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)
    

    Menghasilkan token berikut masing-masing: "==42" dan "==42", "[1,75]","[36, 45]","[36,55]","[36, 75]".

  • Tokenizer JSON dan JSONB (TOKENIZE_JSON dan TOKENIZE_JSONB) digunakan untuk menghasilkan serangkaian token yang mempercepat kesamaan JSON, predikat keberadaan kunci, dan penampungan, seperti doc.key = "value" atau doc[@key] IS NOT NULL (GoogleSQL), dan doc->'key' = '"value"'::jsonb atau doc ? 'key' (PostgreSQL).

Fungsi tokenisasi biasanya digunakan dalam ekspresi kolom yang dihasilkan. Kolom ini didefinisikan sebagai HIDDEN sehingga tidak disertakan dalam hasil kueri SELECT *.

Contoh berikut menggunakan tokenizer teks lengkap dan tokenizer numerik untuk membuat database yang menyimpan nama dan rating album musik. Pernyataan DDL melakukan dua hal:

  1. Menentukan kolom data AlbumTitle dan Rating.
  2. Menentukan AlbumTitle_Tokens dan AlbumRating_Tokens. Kolom TOKENLIST ini melakukan tokenisasi nilai dalam kolom data sehingga Spanner dapat mengindeksnya.

    GoogleSQL

    CREATE TABLE Albums (
      AlbumId STRING(MAX) NOT NULL,
      AlbumTitle STRING(MAX),
      Rating FLOAT64,
      AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
      Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN
    ) PRIMARY KEY(AlbumId);
    

    PostgreSQL

    CREATE TABLE albums (
      albumid character varying NOT NULL,
      albumtitle character varying,
      albumtitle_Tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
    PRIMARY KEY(albumid));
    

Setiap kali nilai dasar diubah, AlbumTitle_Tokens dan Rating_Tokens akan otomatis diperbarui.

Membuat token konten teks biasa atau HTML

Tokenisasi teks mendukung jenis konten teks biasa dan HTML. Gunakan fungsi Spanner TOKENIZE_FULLTEXT untuk membuat token. Kemudian, gunakan pernyataan DDL CREATE SEARCH INDEX untuk membuat indeks penelusuran.

Misalnya, pernyataan DDL CREATE TABLE berikut menggunakan fungsi TOKENIZE_FULLTEXT untuk membuat token dari AlbumTitles di tabel Albums. Pernyataan DDL CREATE SEARCH INDEX membuat indeks penelusuran dengan AlbumTitles_Tokens baru.

GoogleSQL

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  AlbumTitle STRING(MAX),
  AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(AlbumTitle_Tokens)

PostgreSQL

CREATE TABLE albums (
  albumid character varying NOT NULL,
  albumtitle character varying,
  albumtitle_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));

CREATE SEARCH INDEX albumsindex ON albums(albumtitle_tokens)

Proses tokenisasi menggunakan aturan berikut:

  • Tokenisasi tidak mencakup stemming atau koreksi kata yang salah eja. Misalnya, dalam kalimat seperti "A cat was looking at a group of cats", token "cat" diindeks secara terpisah dari token "cats". Dibandingkan dengan mesin telusur lain yang menormalisasi token selama penulisan, Spanner menyediakan opsi untuk memperluas kueri penelusuran agar mencakup berbagai bentuk kata. Untuk mengetahui informasi selengkapnya, lihat Mode kueri yang ditingkatkan.
  • Kata henti (seperti "sebuah") disertakan dalam indeks penelusuran.
  • Penelusuran teks lengkap selalu tidak peka huruf besar/kecil. Proses tokenisasi mengonversi semua token menjadi huruf kecil.

Proses tokenisasi melacak posisi setiap token dalam teks asli. Posisi ini nantinya digunakan untuk mencocokkan frasa. Posisi disimpan dalam indeks penelusuran bersama dengan docid.

Google terus meningkatkan kualitas algoritma tokenisasi. Dalam beberapa kasus, hal ini dapat menyebabkan string ditokenisasi secara berbeda di masa mendatang dari cara tokenisasinya saat ini. Kami memperkirakan kasus seperti ini sangat jarang terjadi. Contohnya adalah jika ada peningkatan dalam segmentasi bahasa China, Jepang, dan Korea (CJK).

Argumen content_type menentukan apakah format konten menggunakan teks biasa atau HTML. Gunakan setelan berikut untuk menyetel content_type:

  • Untuk tokenisasi teks, tetapkan argumen content_type ke "text/plain". Ini adalah setelan default.
  • Untuk tokenisasi HTML, tetapkan argumen content_type ke "text/html". Tanpa argumen ini, tag HTML akan diperlakukan sebagai tanda baca. Dalam mode HTML, Spanner menggunakan heuristik untuk menyimpulkan seberapa menonjol teks di halaman. Misalnya, apakah teks berada di judul atau ukuran font-nya. Atribut yang didukung untuk HTML mencakup small, medium, large, title, dan `link'. Seperti posisi, atribut disimpan bersama token di indeks penelusuran. Tokenisasi tidak membuat token untuk tag HTML apa pun.

Atribut token tidak memengaruhi pencocokan atau hasil fungsi SEARCH atau SEARCH_SUBSTRING. Sinyal tersebut hanya digunakan untuk pemberian peringkat.

Contoh berikut menunjukkan cara melakukan tokenisasi teks:

GoogleSQL

CREATE TABLE T (
  ...
  Text STRING(MAX),
  Html STRING(MAX),
  Text_Tokens TOKENLIST
    AS (TOKENIZE_FULLTEXT(Text, content_type=>"text/plain")) HIDDEN,
  Html_Tokens TOKENLIST
    AS (TOKENIZE_FULLTEXT(Html, content_type=>"text/html")) HIDDEN
) PRIMARY KEY(...);

PostgreSQL

CREATE TABLE t (
  ...
  text character varying,
  html character varying,
  text_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(text, content_type=>"text/plain")) VIRTUAL HIDDEN,
  html_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(html, content_type=>'type/html')) VIRTUAL HIDDEN,
PRIMARY KEY(...));

Penyempurnaan deteksi bahasa dengan argumen language_tag

Tokenisasi mendeteksi bahasa input secara otomatis, secara default. Jika bahasa input diketahui, argumen language_tag dapat digunakan untuk menyaring perilaku ini:

GoogleSQL

AlbumTitle_Tokens TOKENLIST
  AS (TOKENIZE_FULLTEXT(AlbumTitle, language_tag=>"en-us")) HIDDEN

PostgreSQL

albumtitle_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle, language_tag=>'en-us')) VIRTUAL HIDDEN

Sebagian besar aplikasi tidak menentukan argumen language_tag dan mengandalkan deteksi bahasa otomatis. Segmentasi untuk bahasa Asia seperti China, Korea, dan Jepang tidak memerlukan setelan bahasa tokenisasi.

Contoh berikut menunjukkan kasus saat language_tag memengaruhi tokenisasi:

Fungsi tokenisasi Token yang dihasilkan
TOKENIZE_FULLTEXT("A tout pourquoi il y a un parce que") [a, tout, pourquoi, il, ya, un, parce, que]
TOKENIZE_FULLTEXT("A tout pourquoi il y a un parce que", \ language_tag=>"fr") [a, tout, pourquoi, il, y, a, un, parce, que]
TOKENIZE_FULLTEXT("旅 行") Dua token: [旅, 行]
TOKENIZE_FULLTEXT("旅 行", language_tag=>"zh") Satu token: [旅行]

Langkah berikutnya