בדף הזה מוסבר איך להוסיף אינדקסים של חיפוש ואיך להשתמש בהם. חיפוש הטקסט המלא מופעל על רשומות באינדקס החיפוש.
איך משתמשים באינדקסים של חיפוש
אפשר ליצור אינדקס חיפוש בכל העמודות שרוצים להפוך לזמינות לחיפושי טקסט מלא. כדי ליצור אינדקס חיפוש, משתמשים בהצהרת ה-DDL CREATE SEARCH INDEX. כדי לעדכן אינדקס, משתמשים בהצהרת DDL ALTER SEARCH INDEX. Spanner יוצר ומעדכן את אינדקס החיפוש באופן אוטומטי, כולל הוספה ועדכון של נתונים באינדקס החיפוש ברגע שהם משתנים במסד הנתונים.
מחיצות של אינדקס החיפוש
אינדקס חיפוש יכול להיות מחולק למחיצות או לא מחולק למחיצות, בהתאם לסוג השאילתות שרוצים להאיץ.
דוגמה למצב שבו אינדקס מחולק הוא הבחירה הטובה ביותר היא כששאילתות האפליקציה מתייחסות לתיבת דואר אלקטרוני. כל שאילתה מוגבלת לתיבת דואר ספציפית.
דוגמה למצב שבו שאילתה ללא חלוקה למחיצות היא הבחירה הטובה ביותר: שאילתה בכל קטגוריות המוצרים בקטלוג מוצרים.
תרחישי שימוש באינדקס החיפוש
בנוסף לחיפוש טקסט מלא, אינדקסים של חיפוש ב-Spanner תומכים באפשרויות הבאות:
- חיפושי JSON, שהם דרך יעילה ליצור אינדקס ולשאול שאילתות במסמכי JSON ו-JSONB.
- חיפושים של מחרוזות משנה, שהם סוג של שאילתה שמחפשת מחרוזת קצרה יותר (מחרוזת המשנה) בתוך גוף טקסט גדול יותר.
- שילוב תנאים בכל קבוצת משנה של נתונים שנוספו לאינדקס, כולל התאמה מדויקת ומספרית, לסריקת אינדקס יחידה.
מידע נוסף על תרחישי שימוש זמין במאמר חיפוש לעומת אינדקסים משניים.
דוגמה לאינדקס חיפוש
כדי להציג את היכולות של אינדקסים של חיפוש, נניח שיש טבלה שמאחסנת מידע על אלבומי מוזיקה:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX)
) PRIMARY KEY(AlbumId);
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
albumtitle character varying,
PRIMARY KEY(albumid));
ל-Spanner יש כמה פונקציות ליצירת טוקנים. כדי לשנות את הטבלה הקודמת כך שהמשתמשים יוכלו להריץ חיפוש טקסט מלא כדי למצוא שמות של אלבומים, צריך להשתמש בפונקציה TOKENIZE_FULLTEXT כדי ליצור טוקנים משמות של אלבומים. לאחר מכן יוצרים עמודה שמשתמשת בסוג הנתונים TOKENLIST כדי להכיל את הפלט של הטוקניזציה מ-TOKENIZE_FULLTEXT.
בדוגמה הזו, אנחנו יוצרים את העמודה AlbumTitle_Tokens.
GoogleSQL
ALTER TABLE Albums
ADD COLUMN AlbumTitle_Tokens TOKENLIST
AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN;
PostgreSQL
ALTER TABLE albums
ADD COLUMN albumtitle_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN;
בדוגמה הבאה נעשה שימוש ב-DDL CREATE SEARCH INDEX כדי ליצור אינדקס חיפוש (AlbumsIndex) באסימונים AlbumTitle (AlbumTitle_Tokens):
GoogleSQL
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens);
PostgreSQL
בדוגמה הזו נעשה שימוש ב-CREATE SEARCH INDEX.
CREATE SEARCH INDEX albumsindex ON albums(albumtitle_tokens);
אחרי שמוסיפים את אינדקס החיפוש, משתמשים בשאילתות SQL כדי למצוא אלבומים שתואמים לקריטריונים של החיפוש. לדוגמה:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
PostgreSQL
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
יצירה של אינדקס חיפוש וביצוע שאילתה לגבי סכימה עם שם
אפשר ליצור אינדקס חיפוש בסכימה עם שם, כמו בדוגמאות הבאות.
GoogleSQL
CREATE SCHEMA AlbumSchema;
CREATE TABLE AlbumSchema.Albums (
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) STORED HIDDEN,
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumSchema.AlbumsIndex ON AlbumSchema.Albums(AlbumTitle_Tokens);
PostgreSQL
ב-PostgreSQL, אי אפשר להשתמש בשמות מלאים כדי ליצור אינדקסים בסכימות בעלות שם.
CREATE SCHEMA AlbumSchema;
CREATE TABLE AlbumSchema.albums (
albumid character varying NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) STORED HIDDEN,
PRIMARY KEY(albumid)
);
CREATE SEARCH INDEX albumsindex ON AlbumSchema.albums(albumtitle_tokens);
בדוגמאות הבאות מוצגות שאילתות לאינדקס החיפוש בסכימה שצוינה:
GoogleSQL
SELECT AlbumId
FROM AlbumSchema.Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
בדוגמה הבאה נעשה שימוש ברמז לשאילתה כדי להנחות את האופטימיזציה של השאילתה להשתמש באינדקס שנקרא AlbumsIndex בזמן ביצוע השאילתה.
SELECT AlbumId
FROM AlbumSchema.Albums@{FORCE_INDEX="AlbumSchema.AlbumsIndex"}
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
PostgreSQL
ב-PostgreSQL, אי אפשר להשתמש בשמות מלאים כדי ליצור אינדקסים בסכימות בעלות שם.
SELECT albumid
FROM AlbumSchema.albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
בדוגמה הבאה נעשה שימוש ברמז לשאילתה כדי להנחות את האופטימיזציה של השאילתה להשתמש באינדקס שנקרא albumsindex בזמן ביצוע השאילתה.
SELECT albumid
FROM AlbumSchema.albums /*@ FORCE_INDEX = albumsindex */
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
עקביות הנתונים
כשיוצרים אינדקס, Spanner משתמש בתהליכים אוטומטיים כדי למלא מחדש את הנתונים ולוודא שהם עקביים. כשמבצעים פעולות כתיבה, האינדקסים מתעדכנים באותה טרנזקציה. Spanner מבצע באופן אוטומטי בדיקות של עקביות הנתונים.
הגדרות של סכמת אינדקס החיפוש
אינדקסים של חיפוש מוגדרים בעמודה אחת או יותר TOKENLIST בטבלה. אינדקסים של חיפוש כוללים את הרכיבים הבאים:
- טבלת בסיס: טבלת Spanner שצריך להוסיף אותה לאינדקס.
TOKENLISTcolumn: אוסף של עמודות שמגדירות את הטוקנים שצריך ליצור להם אינדקס. אין חשיבות לסדר העמודות.
לדוגמה, בהצהרה הבאה, טבלת הבסיס היא Albums. העמודות TOKENLIST נוצרו ב-AlbumTitle (AlbumTitle_Tokens) ו-Rating (Rating_Tokens).
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
SingerId INT64 NOT NULL,
ReleaseTimestamp INT64 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,
singerid bigint NOT NULL,
releasetimestamp bigint NOT NULL,
albumtitle character varying,
rating double precision,
albumtitle_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
rating_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(rating)) VIRTUAL HIDDEN,
PRIMARY KEY(AlbumId));
משתמשים בהצהרה CREATE SEARCH INDEX הבאה כדי ליצור אינדקס חיפוש באמצעות הטוקנים של AlbumTitle ו-Rating:
GoogleSQL
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens, Rating_Tokens)
PARTITION BY SingerId
ORDER BY ReleaseTimestamp DESC
PostgreSQL
CREATE SEARCH INDEX albumsindex
ON albums(albumtitle_tokens, rating_tokens)
PARTITION BY singerid
ORDER BY releasetimestamp DESC
אלה האפשרויות שזמינות לאינדקסים של חיפושים:
- Partitions: קבוצה אופציונלית של עמודות שמחלקת את אינדקס החיפוש. לרוב, שליפת נתונים מאינדקס עם חלוקה למחיצות יעילה משמעותית יותר משליפת נתונים מאינדקס ללא חלוקה למחיצות. מידע נוסף זמין במאמר בנושא חלוקה למחיצות של אינדקסים של חיפוש.
- עמודת סדר המיון: עמודה אופציונלית
INT64שקובעת את סדר האחזור ממדד החיפוש. מידע נוסף זמין במאמר סדר המיון של אינדקס החיפוש. - שילוב: כמו באינדקסים משניים, אפשר לשלב אינדקסים לחיפוש. אינדקסים של חיפוש משולב משתמשים בפחות משאבים כדי לכתוב ולהצטרף לטבלת הבסיס. מידע נוסף זמין במאמר בנושא אינדקסים משולבים של חיפושים.
- סעיף האפשרויות: רשימה של צמדי מפתח/ערך שמבטלים את הגדרות ברירת המחדל של אינדקס החיפוש.
הפריסה הפנימית של אינדקסים של חיפושים
אלמנט חשוב בייצוג הפנימי של אינדקסים של חיפושים הוא docid, שמשמש כייצוג יעיל מבחינת נפח האחסון של המפתח הראשי של טבלת הבסיס, שיכול להיות ארוך ככל שנדרש. היא גם יוצרת את הסדר של פריסת הנתונים הפנימית בהתאם לעמודות של ORDER BYCREATE SEARCH INDEXהדוח שהמשתמשים סיפקו. הוא מיוצג כמספר שלם אחד או שניים בני 64 ביט.
אינדקסים של חיפוש מיושמים באופן פנימי כמיפוי דו-רמתי:
- טוקנים למזהי מסמכים
- מזהי מסמכים למפתחות ראשיים של טבלת הבסיס
השיטה הזו מאפשרת חיסכון משמעותי בנפח האחסון, כי Spanner לא צריך לאחסן את המפתח הראשי המלא של טבלת הבסיס עבור כל זוג של <token, document>.
יש שני סוגים של אינדקסים פיזיים שמטמיעים את שתי רמות המיפוי:
- אינדקס משני שממפה מפתחות של מחיצות ומזהה מסמך למפתח הראשי של טבלת הבסיס. בדוגמה שבקטע הקודם, המיפוי הוא מ-
{SingerId, ReleaseTimestamp, uid}ל-{AlbumId}. באינדקס המשני מאוחסנות גם כל העמודות שצוינו בסעיףSTORINGשלCREATE SEARCH INDEX. - אינדקס של טוקנים שממפה טוקנים למסמכי docid, בדומה לאינדקסים הפוכים בספרות בנושא אחזור מידע. Spanner שומר אינדקס נפרד של טוקנים לכל
TOKENLISTבאינדקס החיפוש. מבחינה לוגית, באינדקסים של טוקנים מתנהלות רשימות של מסמכי docid לכל טוקן בכל מחיצה (שנקראות באחזור מידע רשימות של פוסטים). הרשימות מסודרות לפי אסימונים כדי לאפשר שליפה מהירה, ובתוך הרשימות נעשה שימוש ב-docid לצורך סידור. אינדקסים של טוקנים נפרדים הם פרט הטמעה שלא נחשף דרך ממשקי ה-API של Spanner.
Spanner תומך באפשרויות הבאות ל-docid.
| אינדקס החיפוש | מזהה מסמך | התנהגות |
|---|---|---|
הסעיף ORDER BY מושמט מאינדקס החיפוש |
{uid} |
מערכת Spanner מוסיפה ערך ייחודי (UID) מוסתר כדי לזהות כל שורה. |
ORDER BY column |
{column, uid} |
מערכת Spanner מוסיפה את העמודה UID כפתרון למקרים של שוויון בין שורות עם אותם ערכים של column במחיצה. |
הערות שימוש:
- העמודה של מזהה המשתמש הפנימי לא נחשפת דרך Spanner API.
- באינדקסים שלא נוסף להם UID, טרנזקציות שמוסיפות שורה עם (מחיצה,סדר מיון) שכבר קיים נכשלות.
לדוגמה, נניח שיש לכם את הנתונים הבאים:
| AlbumId | SingerId | ReleaseTimestamp | SongTitle |
|---|---|---|---|
| a1 | 1 | 997 | ימים יפים |
| a2 | 1 | 743 | עיניים יפות |
בהנחה שהעמודה שלפני המיון היא בסדר עולה, התוכן של אינדקס האסימון SingerId מחלק את התוכן של אינדקס האסימון באופן הבא:
| SingerId | _token | ReleaseTimestamp | uid |
|---|---|---|---|
| 1 | יפה | 743 | uid1 |
| 1 | יפה | 997 | uid2 |
| 1 | ימים | 743 | uid1 |
| 1 | עיניים | 997 | uid2 |
חלוקת אינדקס החיפוש
כש-Spanner מפצל טבלה הוא מחלק את נתוני אינדקס החיפוש כך שכל הטוקנים בשורה מסוימת בטבלת הבסיס נמצאים באותו פיצול. במילים אחרות, אינדקס החיפוש מחולק למסמכים. לאסטרטגיית החלוקה הזו יש השלכות משמעותיות על הביצועים:
- מספר השרתים שכל עסקה מתקשרת איתם נשאר קבוע, ללא קשר למספר האסימונים או למספר העמודות המאונדקסות
TOKENLIST. - שאילתות חיפוש שכוללות כמה ביטויים מותנים מופעלות באופן עצמאי על כל פיצול, וכך נמנעים מהתקורה שקשורה לצירוף מבוזר.
יש שני מצבי הפצה לאינדקסים של חיפוש:
- Uniform sharding (פיצול אחיד) (ברירת מחדל). בחלוקה אחידה, נתונים עם אינדקס של כל שורה בטבלת הבסיס מוקצים באופן אקראי לפיצול אינדקס של מחיצה.
- חלוקה לשברי מידע לפי סדר מיון. בחלוקה לפי סדר מיון, הנתונים של כל שורה בטבלת הבסיס מוקצים לפיצול אינדקס של מחיצה על סמך העמודות
ORDER BY(כלומר, עמודות של מיון מראש). לדוגמה, במקרה של סדר מיון יורד, כל השורות עם ערכי סדר המיון הגדולים ביותר מופיעות בחלוקה הראשונה של אינדקס של מחיצה, והקבוצה הבאה של ערכי סדר המיון מופיעה בחלוקה הבאה.
מצבי השארדינג האלה מגיעים עם פשרה בין סיכוני נקודות חמות לבין עלות השאילתה:
- מומלץ להשתמש באינדקסים אחידים של חיפוש עם חלוקה למקטעים כשדפוסי קריאה או כתיבה באינדקס החיפוש עלולים להוביל לנקודות חמות. פיצול אחיד מפחית את העומס על נקודות חמות על ידי חלוקת עומס הקריאה והכתיבה באופן שווה בין הפיצולים, אבל בתמורה הוא עלול להגדיל את השימוש במשאבים במהלך ביצוע שאילתות. באינדקסים של חיפוש עם חלוקה אחידה, השאילתות צריכות לקרוא את כל הפיצולים במחיצה, בגלל הפיזור האקראי של הנתונים. כשניגשים לאינדקסים עם חלוקה אחידה, Spanner קורא את כל הפיצולים במקביל כדי לצמצם את זמן האחזור הכולל של השאילתה.
- עדיף להשתמש באינדקסים של חיפושים עם חלוקה למקטעים לפי סדר המיון, אם סביר להניח שדפוסי קריאה או כתיבה לא יגרמו לנקודות חמות. הגישה הזו יכולה להפחית את העלות של שאילתות שבהן
ORDER BYתואם ל-ORDER BYשל האינדקס, ומוגדרLIMITנמוך יחסית. כשמריצים שאילתות כאלה, Spanner קורא באופן מצטבר החל מהפיצולים הראשונים של מחיצה, והשאילתה יכולה להסתיים בלי לקרוא את כל הפיצולים אם אפשר להגיע ל-LIMITבשלב מוקדם. מגדירים את מצב השארדינג של אינדקס חיפוש באמצעות פסקה
OPTIONS.
GoogleSQL
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens, Rating_Tokens)
PARTITION BY SingerId
ORDER BY ReleaseTimestamp DESC
OPTIONS (sort_order_sharding = true);
PostgreSQL
מגדירים את מצב השארדינג של אינדקס חיפוש באמצעות פסקה WITH.
CREATE SEARCH INDEX albumsindex
ON albums(albumtitle_tokens, rating_tokens)
PARTITION BY singerid
ORDER BY releasetimestamp DESC
WITH (sort_order_sharding = true);
אם המדיניות sort_order_sharding=false מוגדרת או לא מוגדרת, אינדקס החיפוש נוצר באמצעות חלוקה אחידה.
אינדקסים משולבים של חיפושים
בדומה לאינדקסים משניים, אפשר לשלב אינדקסים של חיפוש בטבלת הורה של טבלת הבסיס. הסיבה העיקרית לשימוש באינדקסים משולבים של חיפוש היא מיקום משותף של נתוני טבלת הבסיס עם נתוני האינדקס למחיצות קטנות. למיקום משותף אופורטוניסטי יש את היתרונות הבאים:
- פעולות כתיבה לא צריכות לבצע אישור דו-שלבי.
- הצטרפויות חוזרות של אינדקס החיפוש לטבלת הבסיס לא מפוזרות.
ההגבלות הבאות חלות על אינדקסים של חיפושים משולבים:
- אפשר לשלב רק אינדקסים עם חלוקה לפי סדר מיון.
- אפשר לשלב אינדקסים של חיפוש רק בטבלאות ברמה העליונה (לא בטבלאות צאצא).
- בדומה לטבלאות משולבות ולאינדקסים משניים, צריך להגדיר את המפתח של טבלת האב כקידומת של העמודות
PARTITION BYבאינדקס החיפוש המשולב.
הגדרה של אינדקס חיפוש משולב
בדוגמה הבאה אפשר לראות איך מגדירים אינדקס חיפוש משולב:
GoogleSQL
CREATE TABLE Singers (
SingerId INT64 NOT NULL
) PRIMARY KEY(SingerId);
CREATE TABLE Albums (
SingerId INT64 NOT NULL,
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(SingerId, AlbumId),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens)
PARTITION BY SingerId,
INTERLEAVE IN Singers
OPTIONS (sort_order_sharding = true);
PostgreSQL
CREATE TABLE singers(
singerid bigint NOT NULL
PRIMARY KEY(singerid));
CREATE TABLE albums(
singerid bigint NOT NULL,
albumid character varying NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist
GENERATED ALWAYS
AS (
spanner.tokenize_fulltext(albumtitle)
) VIRTUAL HIDDEN,
PRIMARY KEY(singerid, albumid)),
INTERLEAVE IN PARENT singers ON DELETE CASCADE;
CREATE
SEARCH INDEX albumsindex
ON
albums(albumtitle_tokens)
PARTITION BY singerid INTERLEAVE IN singers WITH(sort_order_sharding = true);
סדר המיון של אינדקס החיפוש
הדרישות להגדרת סדר המיון של אינדקס החיפוש שונות מהדרישות של אינדקסים משניים.
לדוגמה, נניח את הטבלה הבאה:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
ReleaseTimestamp INT64 NOT NULL,
AlbumName STRING(MAX),
AlbumName_Token TOKENLIST AS (TOKEN(AlbumName)) HIDDEN
) PRIMARY KEY(AlbumId);
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
releasetimestamp bigint NOT NULL,
albumname character varying,
albumname_token spanner.tokenlist
GENERATED ALWAYS AS(spanner.token(albumname)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
יכול להיות שהאפליקציה תגדיר אינדקס משני כדי לחפש מידע באמצעות AlbumName מיון לפי ReleaseTimestamp:
CREATE INDEX AlbumsSecondaryIndex ON Albums(AlbumName, ReleaseTimestamp DESC);
אינדקס החיפוש המקביל נראה כך (הוא משתמש בטוקניזציה של התאמה מדויקת, כי אינדקסים משניים לא תומכים בחיפושי טקסט מלא):
CREATE SEARCH INDEX AlbumsSearchIndex
ON Albums(AlbumName_Token)
ORDER BY ReleaseTimestamp DESC;
סדר המיון של אינדקס החיפוש צריך לעמוד בדרישות הבאות:
- אפשר להשתמש בעמודות
INT64רק כדי להגדיר את סדר המיון של אינדקס חיפוש. עמודות עם גדלים שרירותיים צורכות יותר מדי משאבים באינדקס החיפוש, כי Spanner צריך לאחסן docid לצד כל טוקן. במילים אחרות, אי אפשר להשתמש בסוגTIMESTAMPבעמודה sort order, כיTIMESTAMPמשתמש בדיוק של ננו-שנייה, שלא מתאים למספר שלם של 64 ביט. העמודות של סדר המיון לא יכולות להיות
NULL. יש שתי דרכים לעמוד בדרישה הזו:- מגדירים את עמודת סדר המיון כ-
NOT NULL. - מגדירים את האינדקס כך שערכי NULL יוחרגו.
- מגדירים את עמודת סדר המיון כ-
חותמת זמן משמשת לעיתים קרובות כדי לקבוע את סדר המיון. נהוג להשתמש במיקרו-שניות מאז ראשית זמן יוניקס (Unix epoch) לחותמות זמן כאלה.
בדרך כלל, אפליקציות מאחזרות קודם את הנתונים החדשים ביותר באמצעות אינדקס חיפוש שממוין בסדר יורד.
אינדקסים של חיפושים שסוננו על ידי NULL
אפשר להשתמש בתחביר WHERE column_name IS NOT NULL
כדי להחריג שורות של טבלת בסיס באינדקסים של חיפוש. סינון של ערכי NULL יכול לחול על מפתחות חלוקה למחיצות, על עמודות של סדר מיון ועל עמודות מאוחסנות. אסור לסנן ערכי NULL בעמודות של מערכים מאוחסנים.
דוגמה
GoogleSQL
CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Tokens)
STORING (Genre)
WHERE Genre IS NOT NULL
PostgreSQL
CREATE SEARCH INDEX albumsindex
ON albums(albumtitle_tokens)
INCLUDE (genre)
WHERE genre IS NOT NULL
בשילוב עם סעיף WHERE, השאילתה צריכה לציין את תנאי הסינון NULL (Genre IS NOT NULL בדוגמה הזו). אחרת, כלי האופטימיזציה של השאילתות לא יוכל להשתמש באינדקס החיפוש. מידע נוסף זמין במאמר בנושא דרישות לשאילתות SQL.
אפשר להשתמש בסינון NULL בעמודה שנוצרה כדי להחריג שורות על סמך קריטריונים שרירותיים. מידע נוסף זמין במאמר יצירת אינדקס חלקי באמצעות עמודה שנוצרה.
המאמרים הבאים
- מידע על יצירת טוקנים ועל טוקנייזרים של Spanner
- מידע על אינדקסים מספריים
- מידע נוסף על אינדקסים של JSON
- מידע על חלוקת אינדקס למחיצות