Tokenizzazione

Questa pagina descrive come aggiungere la tokenizzazione alle tabelle. La tokenizzazione è necessaria per creare i token utilizzati nell' indice di ricerca.

La tokenizzazione è il processo di trasformazione dei valori in token. Il metodo utilizzato per tokenizzare un documento determina i tipi e l'efficienza delle ricerche che gli utenti possono eseguire al suo interno.

Spanner fornisce tokenizzatori per testo in linguaggio naturale, sottostringhe, testo letterale, numeri e valori booleani. Lo schema del database utilizza il tokenizzatore che corrisponde al tipo di ricerca necessario per la colonna. I tokenizzatori hanno le seguenti caratteristiche:

  • Ogni tokenizzatore è una funzione SQL che riceve un input, ad esempio una stringa o un numero, e argomenti denominati per opzioni aggiuntive.
  • Il tokenizzatore restituisce un TOKENLIST.

Ad esempio, una stringa di testo The quick brown fox jumps over the lazy dog viene tokenizzata in [the,quick,brown,fox,jumps,over,the,lazy,dog]. Una stringa HTML The <b>apple</b> is <i>red</i> viene tokenizzata in [the,apple,is,red].

I token hanno le seguenti caratteristiche:

  • I token vengono archiviati in colonne che utilizzano il tipo di dati TOKENLIST.
  • Ogni token viene archiviato come una sequenza di byte, con un insieme facoltativo di attributi associati. Ad esempio, nelle applicazioni di ricerca a testo intero, un token è in genere una singola parola di un documento di testo.
  • Quando tokenizza i valori HTML, Spanner genera attributi che indicano la prominenza di un token all'interno del documento. Spanner utilizza questi attributi per l'assegnazione di punteggi per promuovere i termini più importanti (ad esempio un'intestazione).

Tokenizzatori

Spanner supporta le seguenti funzioni di tokenizzazione:

  • Il tokenizzatore di testo intero (TOKENIZE_FULLTEXT) produce token di parole intere per le query in linguaggio naturale.

    Esempio

    Entrambe le seguenti funzioni

    GoogleSQL

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

    PostgreSQL

    Questo esempio utilizza spanner.tokenize_fulltext.

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

    producono gli stessi token: [yellow,apple].

  • Il tokenizzatore di sottostringhe (TOKENIZE_SUBSTRING) genera token per ogni n-gramma di ogni parola. Viene utilizzato per trovare le sottostringhe delle parole in un testo.

    Esempio

    GoogleSQL

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

    PostgreSQL

    Questo esempio utilizza spanner.tokenize_substring.

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

    Produce i seguenti token: [ello,hell,hello,orld,worl,world].

  • Il tokenizzatore di n-grammi (TOKENIZE_NGRAMS) genera n-grammi da un input (senza suddividerlo in parole separate). Viene utilizzato per accelerare i predicati delle espressioni regolari.

    Esempio

    La seguente funzione:

    GoogleSQL

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

    PostgreSQL

    Questo esempio utilizza spanner.tokenize_ngrams.

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

    Produce i seguenti token: ["Big ","ig T","g Ti"," Tim", "Time"].

  • I tokenizzatori di corrispondenza esatta (TOKEN e TOKENIZE_BOOL) vengono utilizzati per cercare le righe contenenti un determinato valore in una delle relative colonne. Ad esempio, un'applicazione che indicizza un catalogo di prodotti potrebbe voler cercare prodotti di un determinato brand e colore.

    Esempi

    Le seguenti funzioni:

    GoogleSQL

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

    PostgreSQL

    Questo esempio utilizza spanner.token.

    spanner.token('hello')
    

    Produce i seguenti token: [hello].

    La seguente funzione:

    GoogleSQL

    TOKENIZE_BOOL(true)
    

    PostgreSQL

    Questo esempio utilizza spanner.tokenize_bool.

    spanner.tokenize_bool(true)
    

    Produce il seguente token: [y].

  • I tokenizzatori di numeri (TOKENIZE_NUMBER) vengono utilizzati per generare un insieme di token che accelerano le ricerche di confronto numerico Per le condizioni di uguaglianza, il token è il numero stesso. Per le condizioni di intervallo (ad esempio rating >= 3.5), l'insieme di token è più elaborato.

    Esempi

    Le seguenti istruzioni di funzione:

    GoogleSQL

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

    PostgreSQL

    Questo esempio utilizza spanner.tokenize_number.

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

    Producono rispettivamente i seguenti token: "==42" e "==42", "[1,75]","[36, 45]","[36,55]","[36, 75]".

  • I tokenizzatori JSON e JSONB (TOKENIZE_JSON e TOKENIZE_JSONB ) vengono utilizzati per generare un insieme di token che accelerano i predicati di contenimento JSON ed esistenza di chiavi, ad esempio doc[@key] IS NOT NULL (GoogleSQL) o doc ? 'key' (PostgreSQL).

Le funzioni di tokenizzazione vengono in genere utilizzate in un' espressione di colonna generata. Queste colonne sono definite come HIDDEN in modo che non siano incluse nei risultati delle query SELECT *.

L'esempio seguente utilizza un tokenizzatore di testo intero e un tokenizzatore numerico per creare un database che memorizza i nomi e le valutazioni degli album musicali. L'istruzione DDL esegue due operazioni:

  1. Definisce le colonne di dati AlbumTitle e Rating.
  2. Definisce AlbumTitle_Tokens e AlbumRating_Tokens. Queste colonne TOKENLIST tokenizzano i valori nelle colonne di dati in modo che Spanner possa indicizzarli.

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

Ogni volta che i valori di base vengono modificati, AlbumTitle_Tokens e Rating_Tokens vengono aggiornati automaticamente.

Tokenizzare testo normale o contenuti HTML

La tokenizzazione del testo supporta i tipi di contenuti di testo normale e HTML. Utilizza la funzione TOKENIZE_FULLTEXT di Spanner per creare i token. Poi utilizza l' CREATE SEARCH INDEX istruzione DDL per generare l'indice di ricerca.

Ad esempio, la seguente istruzione DDL CREATE TABLE utilizza la funzione TOKENIZE_FULLTEXT per creare token da AlbumTitles nella tabella Albums. L'istruzione DDL CREATE SEARCH INDEX crea un indice di ricerca con il nuovo AlbumTitles_Tokens.

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)

Il processo di tokenizzazione utilizza le seguenti regole:

  • La tokenizzazione non include la derivazione o la correzione di parole con errori di ortografia. Ad esempio, in una frase come "A cat was looking at a group of cats", il token "cat" viene indicizzato separatamente dal token "cats". Rispetto ad altri motori di ricerca che normalizzano i token durante le scritture, Spanner offre un'opzione per espandere la query di ricerca in modo da includere diverse forme di parole. Per saperne di più, consulta Modalità query avanzata.
  • Le parole vuote (ad esempio "a") sono incluse nell'indice di ricerca.
  • La ricerca a testo intero non fa distinzione tra maiuscole e minuscole. Il processo di tokenizzazione converte tutti i token in minuscolo.

Il processo di tokenizzazione tiene traccia delle posizioni di ogni token nel testo originale. Queste posizioni vengono utilizzate in un secondo momento per trovare le frasi. Le posizioni vengono memorizzate nell'indice di ricerca insieme ai docid.

Google continua a migliorare gli algoritmi di tokenizzazione. In alcuni casi, in futuro una stringa potrebbe essere tokenizzata in modo diverso rispetto a come viene tokenizzata ora. Prevediamo che questi casi siano estremamente rari. Un esempio è il miglioramento della segmentazione delle lingue cinese, giapponese e coreana (CJK).

L'argomento content_type specifica se il formato dei contenuti utilizza testo normale o HTML. Utilizza le seguenti impostazioni per impostare content_type:

  • Per la tokenizzazione del testo, imposta l'argomento content_type su "text/plain". Questa è l'impostazione predefinita.
  • Per la tokenizzazione HTML, imposta l'argomento content_type su "text/html". Senza questo argomento, i tag HTML vengono trattati come punteggiatura. In modalità HTML, Spanner utilizza l'euristica per dedurre la prominenza del testo nella pagina. Ad esempio, se il testo è in un'intestazione o le dimensioni del carattere. Gli attributi supportati per HTML includono small, medium, large, title e `link'. Come la posizione, l'attributo viene memorizzato insieme al token nell'indice di ricerca. La tokenizzazione non crea token per i tag HTML.

Gli attributi dei token non influiscono sulla corrispondenza o sui risultati della SEARCH o SEARCH_SUBSTRING funzione. Vengono utilizzati solo per il ranking.

L'esempio seguente mostra come tokenizzare il testo:

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

Perfezionare il rilevamento della lingua con l'argomento language_tag

Per impostazione predefinita, la tokenizzazione rileva automaticamente la lingua di input. Quando la lingua di input è nota, è possibile utilizzare un argomento language_tag per perfezionare questo comportamento:

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

La maggior parte delle applicazioni lascia l'argomento language_tag non specificato e si affida invece al rilevamento automatico della lingua. La segmentazione per le lingue asiatiche come cinese, coreano e giapponese non richiede l'impostazione della lingua di tokenizzazione.

Gli esempi seguenti mostrano i casi in cui language_tag influisce sulla tokenizzazione:

Funzione di tokenizzazione Token prodotti
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("旅 行") Due token: [旅, 行]
TOKENIZE_FULLTEXT("旅 行", language_tag=>"zh") Un token: [旅行]

Passaggi successivi