חיפוש נתונים שנוספו לאינדקס
חיפוש נתונים שנוספו לאינדקס ב-BigQuery מאפשר לשפר את ביצועי השאילתות ולצמצם את כמות הנתונים שנסרקים.
אתם יכולים להשתמש בפונקציה SEARCH ובאופרטורים הנתמכים בטבלאות שנוספו לאינדקס כדי לחסוך כמה שיותר בייטים מעובדים ואלפיות שנייה של שימוש ב-slot, במיוחד כשמאחזרים חלק קטן מסך כל השורות.
יצירת אינדקס חיפוש
הטבלה הבאה, שנקראת Logs, משמשת להצגת דרכים שונות לשימוש בפונקציה SEARCH. הטבלה בדוגמה הזו קטנה, אבל בפועל, ככל שהטבלה גדולה יותר, כך השיפור בביצועים באמצעות SEARCH משמעותי יותר.
CREATE TABLE my_dataset.Logs (Level STRING, Source STRING, Message STRING) AS ( SELECT 'INFO' as Level, '65.177.8.234' as Source, 'Entry Foo-Bar created' as Message UNION ALL SELECT 'WARNING', '132.249.240.10', 'Entry Foo-Bar already exists, created by 65.177.8.234' UNION ALL SELECT 'INFO', '94.60.64.181', 'Entry Foo-Bar deleted' UNION ALL SELECT 'SEVERE', '4.113.82.10', 'Entry Foo-Bar does not exist, deleted by 94.60.64.181' UNION ALL SELECT 'INFO', '181.94.60.64', 'Entry Foo-Baz created' );
הטבלה נראית כך:
+---------+----------------+-------------------------------------------------------+ | Level | Source | Message | +---------+----------------+-------------------------------------------------------+ | INFO | 65.177.8.234 | Entry Foo-Bar created | | WARNING | 132.249.240.10 | Entry Foo-Bar already exists, created by 65.177.8.234 | | INFO | 94.60.64.181 | Entry Foo-Bar deleted | | SEVERE | 4.113.82.10 | Entry Foo-Bar does not exist, deleted by 94.60.64.181 | | INFO | 181.94.60.64 | Entry Foo-Baz created | +---------+----------------+-------------------------------------------------------+
יוצרים אינדקס חיפוש בטבלה Logs באמצעות מנתח הטקסט שמוגדר כברירת מחדל:
CREATE SEARCH INDEX my_index ON my_dataset.Logs(ALL COLUMNS);
מידע נוסף על אינדקס החיפוש, ראה ניהול אינדקס החיפוש.
שימוש בפונקציה SEARCH
הפונקציה SEARCH מאפשרת חיפוש של נתונים באמצעות אסימונים.
כדי לבצע אופטימיזציה של החיפושים, מומלץ להשתמש ב-SEARCH עם אינדקס.
אפשר להשתמש בפונקציה SEARCH כדי לחפש בטבלה שלמה או להגביל את החיפוש לעמודות ספציפיות.
חיפוש בטבלה שלמה
השאילתה הבאה מחפשת את הערך bar בכל העמודות בטבלה Logs, ומחזירה את השורות שמכילות את הערך הזה, בלי קשר לאותיות רישיות. מכיוון שאינדקס החיפוש משתמש במנתח הטקסט שמוגדר כברירת מחדל, אין צורך לציין אותו בפונקציה SEARCH.
SELECT * FROM my_dataset.Logs WHERE SEARCH(Logs, 'bar');
+---------+----------------+-------------------------------------------------------+ | Level | Source | Message | +---------+----------------+-------------------------------------------------------+ | INFO | 65.177.8.234 | Entry Foo-Bar created | | WARNING | 132.249.240.10 | Entry Foo-Bar already exists, created by 65.177.8.234 | | INFO | 94.60.64.181 | Entry Foo-Bar deleted | | SEVERE | 4.113.82.10 | Entry Foo-Bar does not exist, deleted by 94.60.64.181 | +---------+----------------+-------------------------------------------------------+
השאילתה הבאה מחפשת את הערך `94.60.64.181` בכל העמודות בטבלה Logs, ומחזירה את השורות שמכילות את הערך הזה. התגים האלה מאפשרים חיפוש מדויק, ולכן השורה האחרונה בטבלה Logs, שמכילה את הערך 181.94.60.64, מושמטת.
SELECT * FROM my_dataset.Logs WHERE SEARCH(Logs, '`94.60.64.181`');
+---------+----------------+-------------------------------------------------------+ | Level | Source | Message | +---------+----------------+-------------------------------------------------------+ | INFO | 94.60.64.181 | Entry Foo-Bar deleted | | SEVERE | 4.113.82.10 | Entry Foo-Bar does not exist, deleted by 94.60.64.181 | +---------+----------------+-------------------------------------------------------+
חיפוש בקבוצת משנה של עמודות
בעזרת SEARCH קל לציין קבוצת משנה של עמודות שבהן רוצים לחפש נתונים. השאילתה הבאה מחפשת את הערך 94.60.64.181 בעמודה Message בטבלה Logs, ומחזירה את השורות שמכילות את הערך הזה.
SELECT * FROM my_dataset.Logs WHERE SEARCH(Message, '`94.60.64.181`');
+---------+----------------+-------------------------------------------------------+ | Level | Source | Message | +---------+----------------+-------------------------------------------------------+ | SEVERE | 4.113.82.10 | Entry Foo-Bar does not exist, deleted by 94.60.64.181 | +---------+----------------+-------------------------------------------------------+
השאילתה הבאה מחפשת גם בעמודה Source וגם בעמודה Message בטבלה Logs. היא מחזירה את השורות שמכילות את הערך 94.60.64.181 מאחת מהעמודות.
SELECT * FROM my_dataset.Logs WHERE SEARCH((Source, Message), '`94.60.64.181`');
+---------+----------------+-------------------------------------------------------+ | Level | Source | Message | +---------+----------------+-------------------------------------------------------+ | INFO | 94.60.64.181 | Entry Foo-Bar deleted | | SEVERE | 4.113.82.10 | Entry Foo-Bar does not exist, deleted by 94.60.64.181 | +---------+----------------+-------------------------------------------------------+
החרגת עמודות מחיפוש
אם בטבלה יש הרבה עמודות ואתם רוצים לחפש ברוב העמודות, יכול להיות שיהיה קל יותר לציין רק את העמודות שאתם רוצים להחריג מהחיפוש. השאילתה הבאה מחפשת בכל העמודות בטבלה Logs, חוץ מהעמודה Message. היא מחזירה את השורות של כל העמודות מלבד Message
שמכילות את הערך 94.60.64.181.
SELECT * FROM my_dataset.Logs WHERE SEARCH( (SELECT AS STRUCT Logs.* EXCEPT (Message)), '`94.60.64.181`');
+---------+----------------+---------------------------------------------------+ | Level | Source | Message | +---------+----------------+---------------------------------------------------+ | INFO | 94.60.64.181 | Entry Foo-Bar deleted | +---------+----------------+---------------------------------------------------+
שימוש בכלי אחר לניתוח טקסט
בדוגמה הבאה נוצרת טבלה בשם contact_info עם אינדקס שמשתמש במנתח הטקסט NO_OP_ANALYZER:
CREATE TABLE my_dataset.contact_info (name STRING, email STRING) AS ( SELECT 'Kim Lee' AS name, 'kim.lee@example.com' AS email UNION ALL SELECT 'Kim' AS name, 'kim@example.com' AS email UNION ALL SELECT 'Sasha' AS name, 'sasha@example.com' AS email ); CREATE SEARCH INDEX noop_index ON my_dataset.contact_info(ALL COLUMNS) OPTIONS (analyzer = 'NO_OP_ANALYZER');
+---------+---------------------+ | name | email | +---------+---------------------+ | Kim Lee | kim.lee@example.com | | Kim | kim@example.com | | Sasha | sasha@example.com | +---------+---------------------+
השאילתה הבאה מחפשת את הערך Kim בעמודה name ואת הערך kim בעמודה email.
מכיוון שאינדקס החיפוש לא משתמש במנתח הטקסט שמוגדר כברירת מחדל, צריך להעביר את שם המנתח לפונקציה SEARCH.
SELECT name, SEARCH(name, 'Kim', analyzer=>'NO_OP_ANALYZER') AS name_Kim, email, SEARCH(email, 'kim', analyzer=>'NO_OP_ANALYZER') AS email_kim FROM my_dataset.contact_info;
הפונקציה NO_OP_ANALYZER לא משנה את הטקסט, ולכן הפונקציה SEARCH מחזירה את הערך TRUE רק במקרים של התאמות מדויקות:
+---------+----------+---------------------+-----------+ | name | name_Kim | email | email_kim | +---------+----------+---------------------+-----------+ | Kim Lee | FALSE | kim.lee@example.com | FALSE | | Kim | TRUE | kim@example.com | FALSE | | Sasha | FALSE | sasha@example.com | FALSE | +---------+----------+---------------------+-----------+
הגדרת האפשרויות של מנתח הטקסט
אפשר להתאים אישית את מנתחי הטקסט LOG_ANALYZER ו-PATTERN_ANALYZER על ידי הוספת מחרוזת בפורמט JSON לאפשרויות ההגדרה. אפשר להגדיר מנתחי טקסט בפונקציה SEARCH, בהצהרת ה-DDL CREATE
SEARCH INDEX ובפונקציה TEXT_ANALYZE.
בדוגמה הבאה נוצרת טבלה בשם complex_table עם אינדקס שמשתמש במנתח הטקסט LOG_ANALYZER. הוא משתמש במחרוזת בפורמט JSON כדי להגדיר את אפשרויות הניתוח:
CREATE TABLE dataset.complex_table( a STRING, my_struct STRUCT<string_field STRING, int_field INT64>, b ARRAY<STRING> ); CREATE SEARCH INDEX my_index ON dataset.complex_table(a, my_struct, b) OPTIONS (analyzer = 'LOG_ANALYZER', analyzer_options = '''{ "token_filters": [ { "normalizer": {"mode": "NONE"} } ] }''');
בטבלה הבאה מוצגות דוגמאות לקריאות לפונקציה SEARCH עם מנתחי טקסט שונים והתוצאות שלהן. הטבלה הראשונה קוראת לפונקציה SEARCH באמצעות מנתח הטקסט שמוגדר כברירת מחדל, LOG_ANALYZER:
| בקשה להפעלת פונקציה | מחזירה | סיבה |
|---|---|---|
| SEARCH('foobarexample', NULL) | שגיאה | הערך של search_terms הוא NULL. |
| SEARCH('foobarexample', '') | שגיאה | הפרמטר search_terms לא מכיל אסימונים. |
| SEARCH('foobar-example', 'foobar example') | TRUE | התווים '-' ו-' ' הם תווים מפרידים. |
| SEARCH('foobar-example', 'foobarexample') | לא נכון | הערך search_terms לא מפוצל. |
| SEARCH('foobar-example', 'foobar\\&example') | TRUE | הלוכסן ההפוך הכפול מבטל את התו & שהוא תו מפריד. |
| SEARCH('foobar-example', R'foobar\&example') | TRUE | הלוכסן ההפוך היחיד משמש כתו בריחה (escape) לאמפרסנד במחרוזת גולמית. |
| SEARCH('foobar-example', '`foobar&example`') | לא נכון | התגים דורשים התאמה מדויקת ל-foobar&example. |
| SEARCH('foobar&example', '`foobar&example`') | TRUE | נמצאה התאמה מדויקת. |
| SEARCH('foobar-example', 'example foobar') | TRUE | אין חשיבות לסדר המונחים. |
| SEARCH('foobar-example', 'foobar example') | TRUE | הטוקנים מומרים לאותיות קטנות. |
| SEARCH('foobar-example', '`foobar-example`') | TRUE | נמצאה התאמה מדויקת. |
| SEARCH('foobar-example', '`foobar`') | לא נכון | תגי Backtick שומרים על אותיות רישיות. |
| SEARCH('`foobar-example`', '`foobar-example`') | לא נכון | למירכאות אחוריות אין משמעות מיוחדת ב-data_to_search וב- |
| SEARCH('foobar@example.com', '`example.com`') | TRUE | נמצאה התאמה מדויקת אחרי התו המפריד ב-data_to_search. |
| SEARCH('a foobar-example b', '`foobar-example`') | TRUE | נמצאה התאמה מדויקת בין התווים המפרידים של הרווחים. |
| SEARCH(['foobar', 'example'], 'foobar example') | לא נכון | אין רשומה אחת במערך שתואמת לכל מונחי החיפוש. |
| SEARCH('foobar=', '`foobar\\=`') | לא נכון | הערך של search_terms שווה ל-foobar\=. |
| SEARCH('foobar=', R'`foobar\=`') | לא נכון | זה שווה ערך לדוגמה הקודמת. |
| SEARCH('foobar=', 'foobar\\=') | TRUE | סימן השוויון הוא מפריד בנתונים ובשאילתה. |
| SEARCH('foobar=', R'foobar\=') | TRUE | זה שווה ערך לדוגמה הקודמת. |
| SEARCH('foobar.example', '`foobar`') | TRUE | נמצאה התאמה מדויקת. |
| SEARCH('foobar.example', '`foobar.`') | לא נכון | המחרוזת `foobar.` לא מנותחת בגלל סימני הגרש ההפוך. היא לא |
| SEARCH('foobar..example', '`foobar.`') | TRUE | `foobar.` לא מנותח בגלל הגרש ההפוך; אחריו מופיע |
בטבלה הבאה מוצגות דוגמאות לקריאות לפונקציה SEARCH באמצעות מנתח הטקסט NO_OP_ANALYZER, וסיבות לערכי החזרה שונים:
| בקשה להפעלת פונקציה | מחזירה | סיבה |
|---|---|---|
| SEARCH('foobar', 'foobar', analyzer=>'NO_OP_ANALYZER') | TRUE | נמצאה התאמה מדויקת. |
| SEARCH('foobar', '`foobar`', analyzer=>'NO_OP_ANALYZER') | לא נכון | תגי backtick הם לא תווים מיוחדים ב-NO_OP_ANALYZER. |
| SEARCH('Foobar', 'foobar', analyzer=>'NO_OP_ANALYZER') | לא נכון | האותיות הרישיות לא תואמות. |
| SEARCH('foobar example', 'foobar', analyzer=>'NO_OP_ANALYZER') | לא נכון | אין מפרידים ל-NO_OP_ANALYZER. |
| SEARCH('', '', analyzer=>'NO_OP_ANALYZER') | TRUE | אין מפרידים ל-NO_OP_ANALYZER. |
אופרטורים ופונקציות אחרים
אתם יכולים לבצע אופטימיזציות של אינדקס החיפוש באמצעות כמה אופרטורים, פונקציות ופרדיקטים.
אופטימיזציה באמצעות אופרטורים ופונקציות השוואה
BigQuery יכול לבצע אופטימיזציה של שאילתות מסוימות שמשתמשות באופרטור השוויון (=), באופרטור IN, באופרטור LIKE, בפונקציה STARTS_WITH או בפונקציה ENDS_WITH כדי להשוות בין מחרוזות מילוליות לבין נתונים שנוסף להם אינדקס.
אופטימיזציה באמצעות פרדיקטים של מחרוזות
אפשר לבצע אופטימיזציה של אינדקס החיפוש באמצעות הפרדיקטים הבאים:
column_name = 'string_literal''string_literal' = column_namestruct_column.nested_field = 'string_literal'string_array_column[OFFSET(0)] = 'string_literal'string_array_column[ORDINAL(1)] = 'string_literal'column_name IN ('string_literal1', 'string_literal2', ...)column_name LIKE 'prefix%'STARTS_WITH(column_name, 'prefix')ENDS_WITH(column_name, 'some suffix')
אופטימיזציה באמצעות פרדיקטים מספריים
אם אינדקס החיפוש נוצר עם סוגי נתונים מספריים, BigQuery יכול לבצע אופטימיזציה של שאילתות מסוימות שמשתמשות באופרטור השוויון (=) או באופרטור IN עם נתונים שנוסף להם אינדקס. אפשר לבצע אופטימיזציה של אינדקס החיפוש באמצעות הפרדיקטים הבאים:
INT64(json_column.int64_field) = 1int64_column = 1int64_array_column[OFFSET(0)] = 1int64_column IN (1, 2)struct_column.nested_int64_field = 1struct_column.nested_timestamp_field = TIMESTAMP "2024-02-15 21:31:40"timestamp_column = "2024-02-15 21:31:40"timestamp_column IN ("2024-02-15 21:31:40", "2024-02-16 21:31:40")
אופטימיזציה של פונקציות שמפיקות נתונים שנוספו לאינדקס
BigQuery תומך באופטימיזציה של אינדקס החיפוש כשפונקציות מסוימות מופעלות על נתונים שנוסף להם אינדקס.
אם אינדקס החיפוש משתמש במנתח הטקסט שמוגדר כברירת מחדל, LOG_ANALYZER, אפשר להחיל על העמודה את הפונקציות UPPER או LOWER, למשל UPPER(column_name) = 'STRING_LITERAL'.
בנתוני מחרוזת סקלריים מסוג JSON שחולצו מעמודה מסוג JSON שנוסף לה אינדקס, אפשר להפעיל את הפונקציה STRING או את הגרסה הבטוחה שלה, SAFE.STRING.
אם הערך של JSON שחולץ הוא לא מחרוזת, הפונקציה STRING מייצרת שגיאה והפונקציה SAFE.STRING מחזירה את הערך NULL.
אפשר להחיל את הפונקציות הבאות על נתוני STRING (לא JSON) בפורמט JSON שנוספו לאינדקס:
לדוגמה, נניח שיש לכם את הטבלה הבאה שנוסף לה אינדקס, בשם dataset.person_data, עם העמודות JSON ו-STRING:
+----------------------------------------------------------------+-----------------------------------------+
| json_column | string_column |
+----------------------------------------------------------------+-----------------------------------------+
| { "name" : "Ariel", "email" : "cloudysanfrancisco@gmail.com" } | { "name" : "Ariel", "job" : "doctor" } |
+----------------------------------------------------------------+-----------------------------------------+
אפשר לבצע אופטימיזציה לשאילתות הבאות:
SELECT * FROM dataset.person_data WHERE SAFE.STRING(json_column.email) = 'cloudysanfrancisco@gmail.com';
SELECT * FROM dataset.person_data WHERE JSON_VALUE(string_column, '$.job') IN ('doctor', 'lawyer', 'teacher');
גם שילובים של הפונקציות האלה עוברים אופטימיזציה, למשל UPPER(JSON_VALUE(json_string_expression)) = 'FOO'.
אופטימיזציה באמצעות JSON_FLATTEN
ב-BigQuery יש תמיכה באופטימיזציה של אינדקס החיפוש לשאילתות שמשתמשות בפונקציה JSON_FLATTEN כדי לשטח מערכי JSON, בדרך כלל בשילוב עם EXISTS ו-UNNEST.
לדוגמה, נניח שיש לכם טבלה בשם dataset.logs עם עמודת JSON בשם json_payload. השאילתה הבאה עומדת בדרישות לאופטימיזציה:
SELECT json_payload FROM dataset.logs WHERE EXISTS( SELECT 1 FROM UNNEST(JSON_FLATTEN(JSON_QUERY(json_payload, "lax recursive $.message"))) AS f WHERE SEARCH(f, "nullpointerexception") );
השימוש באינדקס החיפוש
כדי לקבוע אם נעשה שימוש באינדקס חיפוש בשאילתה, אפשר להציג את פרטי המשימה או לשלוח שאילתה לאחת מהתצוגות של INFORMATION_SCHEMA.JOBS*.
צפייה בפרטי המשרה
בקטע Job Information של Query results, השדות Index Usage Mode ו-Index Unused Reasons מספקים מידע מפורט על השימוש באינדקס החיפוש.
מידע על השימוש באינדקס החיפוש זמין גם דרך השדה searchStatistics ב-API Jobs.Get. השדה indexUsageMode ב-searchStatistics מציין אם נעשה שימוש באינדקס חיפוש עם הערכים הבאים:
-
UNUSED: לא נעשה שימוש באינדקס חיפוש. -
PARTIALLY_USED: חלק מהשאילתה השתמש באינדקסי חיפוש וחלק לא. -
FULLY_USED: כל פונקצייתSEARCHבשאילתה השתמשה באינדקס חיפוש.
כשהערך של indexUsageMode הוא UNUSED או PARTIALLY_USED, השדה indexUnusedReasons מכיל מידע על הסיבה לכך שלא נעשה שימוש באינדקסי חיפוש בשאילתה.
כדי לראות את searchStatistics של שאילתה, מריצים את הפקודה bq show.
bq show --format=prettyjson -j JOB_ID
דוגמה
נניח שאתם מריצים שאילתה שקוראת לפונקציה SEARCH על נתונים בטבלה. אפשר להציג את פרטי המשימה של השאילתה כדי למצוא את מזהה המשימה, ואז להריץ את הפקודה bq show כדי לראות מידע נוסף:
bq show --format=prettyjson --j my_project:US.bquijob_123x456_789y123z456c
הפלט מכיל שדות רבים, כולל searchStatistics, שנראה בערך כך: בדוגמה הזו, הערך indexUsageMode מציין שלא נעשה שימוש באינדקס. הסיבה לכך היא שלטבלה אין אינדקס חיפוש. כדי לפתור את הבעיה, יוצרים אינדקס חיפוש בטבלה. indexUnusedReason code field מפרט את כל הסיבות לכך שאינדקס החיפוש לא משמש בשאילתה.
"searchStatistics": {
"indexUnusedReasons": [
{
"baseTable": {
"datasetId": "my_dataset",
"projectId": "my_project",
"tableId": "my_table"
},
"code": "INDEX_CONFIG_NOT_AVAILABLE",
"message": "There is no search index configuration for the base table `my_project:my_dataset.my_table`."
}
],
"indexUsageMode": "UNUSED"
},
שליחת שאילתות לתצוגות של INFORMATION_SCHEMA
אתם יכולים גם לראות את השימוש באינדקס החיפוש של כמה משימות באזור בתצוגות הבאות:
INFORMATION_SCHEMA.JOBSINFORMATION_SCHEMA.JOBS_BY_USERINFORMATION_SCHEMA.JOBS_BY_FOLDERINFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
השאילתה הבאה מציגה מידע על השימוש באינדקס לכל השאילתות שאפשר לבצע להן אופטימיזציה של אינדקס החיפוש ב-7 הימים האחרונים:
SELECT job_id, search_statistics.index_usage_mode, index_unused_reason.code, index_unused_reason.base_table.table_id, index_unused_reason.index_name FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS, UNNEST(search_statistics.index_unused_reasons) AS index_unused_reason WHERE end_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) AND CURRENT_TIMESTAMP();
התוצאה אמורה להיראות כך:
+-----------+----------------------------------------+-----------------------+ | job_id | index_usage_mode | code | table_id | index_name | +-----------+------------------+---------------------+-----------------------+ | bquxjob_1 | UNUSED | BASE_TABLE_TOO_SMALL| my_table | my_index | | bquxjob_2 | FULLY_USED | NULL | my_table | my_index | +-----------+----------------------------------------+-----------------------+
שיטות מומלצות
בקטעים הבאים מתוארות שיטות מומלצות לחיפוש.
חיפוש סלקטיבי
החיפוש פועל בצורה הטובה ביותר כשיש מעט תוצאות. החיפושים צריכים להיות ספציפיים ככל האפשר.
אופטימיזציה של ORDER BY LIMIT
כדי לבצע אופטימיזציה של שאילתות שמשתמשות ב-SEARCH, =, IN, LIKE או STARTS_WITH בטבלה מחולקת למחיצות גדולה מאוד, אפשר להשתמש בסעיף ORDER BY בשדה המחולק למחיצות ובסעיף LIMIT.
בשאילתות שלא מכילות את הפונקציה SEARCH, אפשר להשתמש באופרטורים ובפונקציות אחרות כדי לנצל את האופטימיזציה. האופטימיזציה חלה גם אם הטבלה נוספה לאינדקס וגם אם לא. השיטה הזו מתאימה אם אתם מחפשים מונח נפוץ.
לדוגמה, נניח שהטבלה Logs שנוצרה קודם חולקה למחיצות לפי עמודה נוספת מסוג DATE בשם day. השאילתה הבאה עברה אופטימיזציה:
SELECT Level, Source, Message FROM my_dataset.Logs WHERE SEARCH(Message, "foo") ORDER BY day LIMIT 10;
היקף החיפוש
כשמשתמשים בפונקציה SEARCH, צריך לחפש רק בעמודות בטבלה שצפויות להכיל את מונחי החיפוש. כך אפשר לשפר את הביצועים ולהפחית את מספר הבייטים שצריך לסרוק.
שימוש בסימני הטעמה משנית (backticks)
כשמשתמשים בפונקציה SEARCH עם מנתח הטקסט LOG_ANALYZER, הוספת מירכאות הפוכות לשאילתת החיפוש מאלצת התאמה מדויקת. זה שימושי אם החיפוש תלוי אותיות רישיות או מכיל תווים שלא אמורים להתפרש כמפרידים. לדוגמה, כדי לחפש את כתובת ה-IP 192.0.2.1, משתמשים ב-`192.0.2.1`. בלי התווים האלה, החיפוש יחזיר כל שורה שמכילה את הטוקנים הנפרדים 192, 0, 2 ו-1, בכל סדר שהוא.