בנוסף להוספת טקסט לאינדקס, אינדקס החיפוש מספק דרך יעילה להוספת מספרים לאינדקס. הוא משמש בעיקר להרחבת שאילתות של חיפוש טקסט מלא עם תנאים בשדות מספריים. בדף הזה מוסבר איך להוסיף לאינדקס מספרים לשאילתות שוויון ואי-שוויון, ואיך להוסיף לאינדקס מערך של מספרים.
המרת מספרים לטוקנים
מנתחי מספרים משמשים ליצירת קבוצה של אסימונים שמשמשים להאצת חיפושים של השוואות מספריות.
משתמשים בפונקציה TOKENIZE_NUMBER כדי ליצור אינדקס מספרי. TOKENIZE_NUMBER תומך ב-INT64, ב-FLOAT32, ב-FLOAT64 או ב-ARRAY מהסוגים האלה.
ב-PostgreSQL, משתמשים בפונקציה spanner.tokenize_number כדי ליצור אינדקס מספרי. השדה spanner.tokenize_number תומך רק בסוג bigint.
מספרי אינדקס לשאילתות שוויון ואי-שוויון
ב-Spanner אפשר להוסיף לאינדקס מספרים של שוויון ואי-שוויון.
חיפושים של שוויון תואמים למספר. חיפושים של טווחים ואי-שוויונים תואמים למספר בטווח מסוים. מגדירים את הערך הזה בפרמטר TOKENIZE_NUMBER
comparison_type:
- שוויון:
comparison_type=>"equality" - אי-שוויון ושוויון:
comparison_type=>"all"
בשני המקרים, המספר המקורי (מספר שלם או מספר עם נקודה צפה) עובר תהליך של טוקניזציה, שדומה מבחינה רעיונית לטוקניזציה של טקסט מלא. הוא יוצר קבוצה של אסימונים שהשאילתה יכולה להשתמש בהם כדי לאתר מסמכים שתואמים לתנאי המספר.
הוספה לאינדקס של שוויון יוצרת רק אסימון אחד, שמייצג את המספר. מומלץ להשתמש במצב הזה אם השאילתות מכילות רק תנאים בפורמט field = @p בסעיף WHERE.
הוספה לאינדקס של אי-שוויון ושוויון יכולה להאיץ מגוון רחב יותר של תנאים בסעיף WHERE של השאילתה. האופרטורים האלה כוללים את field < @p, field <= @p, field > @p, field >= @p, field BETWEEN @p1 and @p2 ו-field <> @p, בנוסף לתנאי שוויון. כדי להטמיע את סוג ההוספה לאינדקס, Spanner יוצר אסימונים באינדקס החיפוש הבסיסי.
Spanner יכול ליצור הרבה אסימונים לכל מספר שנוסף לאינדקס, בהתאם לפרמטרים של הכוונון. מספר הטוקנים תלוי בפרמטרים שמוגדרים ל-TOKENIZE_NUMBER, כמו algorithm, min, max ו-granularity. לכן חשוב להעריך בקפידה את הפרמטרים של הכוונון כדי להבטיח איזון מתאים בין נפח האחסון בדיסק לבין זמן החיפוש.
בשאילתות טווח על סוגי מספרים שלמים כמו INT64, ציון algorithm =>
"prefixtree" יכול לשפר משמעותית את הביצועים בהשוואה לאלגוריתם ברירת המחדל logtree. האלגוריתם הזה יוצר אסימונים על סמך קידומות של מספרים, וכך מאפשר גיזום יעיל יותר של מרחב החיפוש לתנאי טווח (לדוגמה, <= ו->=). בשאילתות שבהן משפט ה-WHERE מכיל פרדיקטים של טווח, האלגוריתם prefixtree יוצר פחות אסימוני אינדקס למספרים קטנים בהשוואה ל-logtree, מה שיכול לשפר את הביצועים ואת עלות האחסון.
יצירת טוקנים של מערך
בנוסף לערכים סקלריים, TOKENIZE_NUMBER תומך גם בטוקניזציה של מערך מספרים (הדוגמאות בקטע הזה הן למסדי נתונים בניב GoogleSQL. ב-PostgreSQL אין תמיכה בהאצה של מערך מספרים באמצעות אינדקסים של חיפוש).
כשמשתמשים ב-TOKENIZE_NUMBER עם העמודה ARRAY, צריך לציין את comparison_type=>"equality". אי אפשר להשתמש בשאילתות טווח עם מערך של מספרים.
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Ratings ARRAY<INT64>,
Ratings_Tokens TOKENLIST
AS (TOKENIZE_NUMBER(Ratings, comparison_type=>"equality")) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex ON Albums(Ratings_Tokens);
```
The following query finds all albums that have a rating of 1 or 2:
```sql
SELECT AlbumId
FROM Albums
WHERE ARRAY_INCLUDES_ANY(Ratings, [1, 2])
```
The following query finds all albums that were rated as 1 and as 5:
```sql
SELECT AlbumId
FROM Albums
WHERE ARRAY_INCLUDES_ALL(Ratings, [1, 5])
```
### Options for indexing high-precision numbers not supported by `TOKENIZE_NUMBER`
If you need to perform search queries on numeric types not directly supported by
`TOKENIZE_NUMBER` (such as `NUMERIC` or `BIGNUMERIC`),
consider these options:
* **Schema Modification:** Change the column type to `INT64` for the subset of
data that fits within the `INT64` range. Handle values exceeding the `INT64`
range separately, potentially in a different table or using application
logic.
* **Conceptual Mapping to Supported Types:** Explore creating generated
columns to map the `NUMERIC` values to an `INT64` range. This would allow
`TOKENIZE_NUMBER` to be used on the generated column. Be sure to validate
the query results against the original `NUMERIC` column in case your mapping
does not perfectly preserve precision. The specifics of the mapping function
needed for this approach are highly dependent on your specific data.
## What's next
* Learn about [tokenization and Spanner
tokenizers](/spanner/docs/full-text-search/tokenization).
* Learn about [search indexes](/spanner/docs/full-text-search/search-indexes).
* Learn about [index
partitioning](/spanner/docs/full-text-search/partition-search-index).