בדף הזה מוסבר איך להוסיף טבלאות עם טוקניזציה. הטוקניזציה נחוצה כדי ליצור את הטוקנים שמשמשים באינדקס החיפוש.
טוקניזציה היא תהליך של הפיכת ערכים לטוקנים. השיטה שבה משתמשים כדי להמיר מסמך לאסימונים קובעת את סוגי החיפושים שהמשתמשים יכולים לבצע בו ואת היעילות שלהם.
ב-Spanner יש כלי טוקניזציה לטקסט בשפה טבעית, למחרוזות משנה, לטקסט מילולי, למספרים ולערכים בוליאניים. הסכימה של מסד הנתונים משתמשת ב-tokenizer שתואם לסוג החיפוש שנדרש לעמודה. אלה המאפיינים של כלי הטוקניזציה:
- כל טוקנייזר הוא פונקציית SQL שמקבלת קלט, כמו מחרוזת או מספר, וארגומנטים בעלי שם לאפשרויות נוספות.
- הפלט של כלי ההמרה לאסימונים הוא
TOKENLIST.
לדוגמה, מחרוזת הטקסט The quick brown fox jumps over the lazy dog
עוברת טוקניזציה ל-[the,quick,brown,fox,jumps,over,the,lazy,dog].
מחרוזת HTML The <b>apple</b> is <i>red</i> עוברת טוקניזציה ל-[the,apple,is,red].
לאסימונים יש את המאפיינים הבאים:
- האסימונים מאוחסנים בעמודות שמשתמשות בסוג הנתונים
TOKENLIST. - כל אסימון מאוחסן כרצף של בייטים, עם קבוצה אופציונלית של מאפיינים משויכים. לדוגמה, באפליקציות של טקסט מלא, אסימון הוא בדרך כלל מילה אחת ממסמך טקסט.
- כשמבצעים טוקניזציה של ערכי HTML, Spanner יוצר מאפיינים שמציינים את מידת הבולטוּת של טוקן במסמך. Spanner משתמש במאפיינים האלה לדירוג כדי להבליט מונחים חשובים יותר (כמו כותרת).
כלים ליצירת טוקנים
Spanner תומך בפונקציות הבאות של טוקניזציה:
כלי ליצירת אסימונים של טקסט מלא (
TOKENIZE_FULLTEXT) יוצר אסימונים של מילים שלמות לשאילתות בשפה טבעית.דוגמה
שתי הפונקציות הבאות
GoogleSQL
TOKENIZE_FULLTEXT("Yellow apple") TOKENIZE_FULLTEXT("Yellow <b>apple</b>", content_type=>"text/html")PostgreSQL
בדוגמה הזו נשתמש ב-
spanner.tokenize_fulltext.spanner.tokenize_fulltext("Yellow apple") spanner.tokenize_fulltext('Yellow <b>apple</b>', context_type=>'text/html')יפיקו את אותם טוקנים:
[yellow,apple].Substring tokenizer (
TOKENIZE_SUBSTRING) יוצר טוקנים לכל n-gram של כל מילה. היא משמשת למציאת מחרוזות משנה של מילים בטקסט.דוגמה
GoogleSQL
TOKENIZE_SUBSTRING('hello world', ngram_size_min=>4, ngram_size_max=>6)PostgreSQL
בדוגמה הזו נעשה שימוש ב-
spanner.tokenize_substring.spanner.tokenize_substring('hello world', ngram_size_min=>4, ngram_size_max=>6)הפלט של הפקודה הוא הטוקנים הבאים:
[ello,hell,hello,orld,worl,world].N-gram tokenizer (
TOKENIZE_NGRAMS) יוצר n-grams מקלט (בלי לפצל אותו למילים נפרדות). הוא משמש להאצת פרדיקטים של ביטויים רגולריים.דוגמה
הפונקציה הבאה:
GoogleSQL
TOKENIZE_NGRAMS("Big Time", ngram_size_min=>4, ngram_size_max=>4)PostgreSQL
בדוגמה הזו נעשה שימוש ב-
spanner.tokenize_ngrams.spanner.tokenize_ngrams('big time', ngram_size_min=>4, ngram_size_max=>4)התוצאה היא הטוקנים הבאים:
["Big ","ig T","g Ti"," Tim", "Time"].אמצעי טוקניזציה של התאמה מדויקת (
TOKENו-TOKENIZE_BOOL) משמשים לחיפוש שורות שמכילות ערך מסוים באחת מהעמודות שלהן. לדוגמה, באפליקציה שמוסיפה לאינדקס קטלוג מוצרים, יכול להיות שתרצו לחפש מוצרים של מותג וצבע מסוימים.דוגמאות
הפונקציות הבאות:
GoogleSQL
TOKEN("hello") TOKEN(["hello", "world"])PostgreSQL
בדוגמה הזו נשתמש ב-
spanner.token.spanner.token('hello')התוצאה היא הטוקנים הבאים:
[hello].הפונקציה הבאה:
GoogleSQL
TOKENIZE_BOOL(true)PostgreSQL
בדוגמה הזו נשתמש ב-
spanner.tokenize_bool.spanner.tokenize_bool(true)התוצאה היא האסימון הבא:
[y].מספרי טוקנים (
TOKENIZE_NUMBER) משמשים ליצירת קבוצה של טוקנים שמאיצים חיפושים של השוואות מספריות. בתנאי שוויון, האסימון הוא המספר עצמו. בתנאים של טווח (כמוrating >= 3.5), קבוצת האסימונים מורכבת יותר.דוגמאות
הצהרות הפונקציה הבאות:
GoogleSQL
TOKENIZE_NUMBER(42, comparison_type=>'equality') TOKENIZE_NUMBER(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)PostgreSQL
בדוגמה הזו נשתמש ב-
spanner.tokenize_number.spanner.tokenize_number(42, comparison_type=>'equality') spanner.tokenize_number(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)יוצרים את הטוקנים הבאים, בהתאמה:
"==42"ו-"==42","[1,75]","[36, 45]","[36,55]","[36, 75]".JSON and JSONB tokenizers (
TOKENIZE_JSONו-TOKENIZE_JSONB) משמשים ליצירת קבוצה של טוקנים שמאיצים את השוואת ה-JSON, את ההכלה ואת פרדיקטים של קיום מפתח, כמוdoc.key = "value"אוdoc[@key] IS NOT NULL(GoogleSQL) ו-doc->'key' = '"value"'::jsonbאוdoc ? 'key'(PostgreSQL).
בדרך כלל משתמשים בפונקציות של טוקניזציה בביטוי של עמודה שנוצרה. העמודות האלה מוגדרות כ-HIDDEN כדי שלא ייכללו בתוצאות השאילתה של SELECT *.
בדוגמה הבאה נעשה שימוש ב-tokenizer של טקסט מלא וב-tokenizer מספרי כדי ליצור מסד נתונים שמאחסן שמות ודירוגים של אלבומי מוזיקה. הצהרת ה-DDL מבצעת שני דברים:
- מגדיר את עמודות הנתונים
AlbumTitleו-Rating. מגדיר את
AlbumTitle_Tokensו-AlbumRating_Tokens. העמודותTOKENLISTהאלה יוצרות אסימונים מהערכים בעמודות הנתונים, כדי ש-Spanner יוכל להוסיף אותם לאינדקס.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));
בכל פעם שמשנים את ערכי הבסיס, AlbumTitle_Tokens ו-Rating_Tokens מתעדכנים באופן אוטומטי.
יצירת טוקנים מתוכן טקסט פשוט או HTML
טוקניזציה של טקסט תומכת בטקסט פשוט ובסוגי תוכן HTML. משתמשים בפונקציה TOKENIZE_FULLTEXT של Spanner כדי ליצור טוקנים. ואז משתמשים בהצהרת ה-DDL CREATE SEARCH INDEX כדי ליצור את אינדקס החיפוש.
לדוגמה, הצהרת ה-DDL הבאה ב-CREATE TABLE משתמשת בפונקציה TOKENIZE_FULLTEXT כדי ליצור אסימונים מ-AlbumTitles בטבלה Albums. הצהרת ה-DDL CREATE SEARCH INDEX יוצרת אינדקס חיפוש עם 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)
תהליך הטוקניזציה מתבסס על הכללים הבאים:
- הטוקניזציה לא כוללת הטיה או תיקון של שגיאות כתיב. לדוגמה, במשפט 'חתול הסתכל על קבוצה של חתולים', האסימון 'חתול' מאונדקס בנפרד מהאסימון 'חתולים'. בניגוד למנועי חיפוש אחרים שמנרמלים אסימונים במהלך כתיבה, Spanner מספק אפשרות להרחיב את שאילתת החיפוש כך שתכלול צורות שונות של מילים. מידע נוסף מופיע במאמר בנושא מצב שאילתה משופר.
- מילות עצירה (כמו 'a') נכללות באינדקס החיפוש.
- חיפוש טקסט מלא הוא תמיד לא תלוי-רישיות. תהליך הטוקניזציה ממיר את כל הטוקנים לאותיות קטנות.
תהליך הטוקניזציה עוקב אחרי המיקומים של כל טוקן בטקסט המקורי. המיקומים האלה משמשים בהמשך להתאמת ביטויים. המיקומים נשמרים באינדקס החיפוש לצד מספרי המסמכים.
Google ממשיכה לשפר את האלגוריתמים של הטוקניזציה. במקרים מסוימים, יכול להיות שבעתיד מחרוזת תעבור טוקניזציה בצורה שונה מהאופן שבו היא עוברת טוקניזציה עכשיו. מקרים כאלה אמורים להיות נדירים ביותר. דוגמה לכך היא שיפור בפילוח של שפות סיניות, יפניות וקוריאניות (CJK).
הארגומנט content_type מציין אם פורמט התוכן הוא טקסט פשוט או HTML. כדי להגדיר את content_type, משתמשים בהגדרות הבאות:
- כדי להגדיר טוקניזציה של טקסט, מגדירים את הארגומנט
content_typeלערךtext/plain. זו הגדרת ברירת המחדל. - כדי לבצע טוקניזציה של HTML, צריך להגדיר את הארגומנט
content_typeל-"text/html". בלי הארגומנט הזה, תגי HTML מטופלים כסימני פיסוק. במצב HTML, Spanner משתמש בהיוריסטיקה כדי להסיק עד כמה הטקסט בולט בדף. לדוגמה, אם הטקסט נמצא בכותרת או מה גודל הגופן שלו. המאפיינים הנתמכים של HTML כוללים אתsmall,medium,large,titleו-`link'. בדומה למיקום, המאפיין מאוחסן לצד האסימון באינדקס החיפוש. הטוקניזציה לא יוצרת אסימונים לתגי HTML.
מאפייני טוקנים לא משפיעים על ההתאמה או על התוצאות של הפונקציה SEARCH או SEARCH_SUBSTRING. הם משמשים רק לדירוג.
בדוגמה הבאה אפשר לראות איך להמיר טקסט לטוקנים:
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(...));
שיפור זיהוי השפה באמצעות הארגומנט language_tag
כברירת מחדל, תהליך הטוקניזציה מזהה את שפת הקלט באופן אוטומטי. כאשר שפת הקלט ידועה, אפשר להשתמש בארגומנט language_tag כדי לשפר את ההתנהגות הזו:
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
ברוב האפליקציות לא מציינים את הארגומנט language_tag, אלא מסתמכים על זיהוי שפה אוטומטי. כדי לפלח שפות אסיאתיות כמו סינית, קוריאנית ויפנית, לא צריך להגדיר את שפת הטוקניזציה.
בדוגמאות הבאות מוצגים מקרים שבהם language_tag משפיע על הטוקניזציה:
| פונקציית טוקניזציה | טוקנים שנוצרו |
|---|---|
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("旅 行") |
שני טוקנים: [旅, 行] |
TOKENIZE_FULLTEXT("旅 行", language_tag=>"zh") |
טוקן אחד: [旅行] |