עבודה עם מנתחי טקסט

הגדרת מנתחי טקסט מתקדמים ב-BigQuery מאפשרת לכם לשפר את חוויית החיפוש על ידי שליטה מדויקת באופן שבו נתוני המחרוזת עוברים המרה לאסימונים. אם תפעילו הגדרות אישיות על אינדקסי החיפוש, כמו תבניות של ביטויים רגולריים ומסננים של מילות עצירה, תוכלו לקבוע בדיוק איך הפונקציה תעריך את הטקסט ותתאים אותו. אתם יכולים להגדיר מנתחי טקסט מתקדמים להצהרת ה-DDL‏ CREATE SEARCH INDEX, לפונקציה SEARCH ולפונקציה TEXT_ANALYZE.

מנתחי טקסט

ב-BigQuery אפשר להשתמש במנתחי הטקסט הבאים:

  • NO_OP_ANALYZER
  • LOG_ANALYZER
  • PATTERN_ANALYZER

NO_OP_ANALYZER

כדאי להשתמש ב-NO_OP_ANALYZER כשיש נתונים שעברו עיבוד מראש ורוצים להתאים אותם באופן מדויק. לא מתבצעת טוקניזציה או נורמליזציה של הטקסט. מכיוון שהמנתח הזה לא מבצע טוקניזציה או נורמליזציה, הוא לא מקבל הגדרות אישיות. מידע נוסף על NO_OP_ANALYZER זמין במאמר NO_OP_ANALYZER.

LOG_ANALYZER

ה-LOG_ANALYZER משנה את הנתונים בדרכים הבאות:

  • הטקסט מומר לאותיות קטנות.
  • ערכי ASCII שגדולים מ-127 נשמרים כמו שהם.

  • הטקסט מחולק למונחים נפרדים שנקראים אסימונים, באמצעות התווים המפרידים הבאים:

    [ ] < > ( ) { } | ! ; , ' " * & ? + / : = @ . - $ % \ _ \n \r \s \t %21 %26
    %2526 %3B %3b %7C %7c %20 %2B %2b %3D %3d %2520 %5D %5d %5B %5b %3A %3a %0A
    %0a %2C %2c %28 %29
    

    אם אתם לא רוצים להשתמש בתווי ההפרדה שמוגדרים כברירת מחדל, אתם יכולים לציין את תווי ההפרדה שבהם אתם רוצים להשתמש כאפשרויות לניתוח טקסט. LOG_ANALYZER מאפשר להגדיר מפרידים ספציפיים ומסנני אסימונים כדי לשלוט טוב יותר בתוצאות החיפוש. למידע נוסף על אפשרויות ההגדרה הספציפיות שזמינות כשמשתמשים ב-LOG_ANALYZER, קראו את המאמרים אפשרות הניתוח delimiters ואפשרות הניתוח token_filters.

PATTERN_ANALYZER

מנתח הטקסט PATTERN_ANALYZER מחלץ אסימונים מטקסט באמצעות ביטוי רגולרי. מנוע הביטויים הרגולריים והתחביר שמשמשים ב-PATTERN_ANALYZER הם RE2. ‫PATTERN_ANALYZER יוצר אסימונים לתבניות בסדר הבא:

  1. היא מוצאת את מחרוזת המשנה הראשונה שתואמת לתבנית (משמאל) במחרוזת. זהו טוקן שצריך לכלול בפלט.
  2. היא מסירה את כל מה שמופיע במחרוזת הקלט עד לסוף מחרוזת המשנה שנמצאה בשלב 1.
  3. הוא חוזר על התהליך עד שהמחרוזת ריקה.

בטבלה הבאה מוצגות דוגמאות לחילוץ אסימונים של PATTERN_ANALYZER:

דוגמת קוד הטקסט שהוזן טוקנים של פלט
ab ababab
  • ab
ab abacad
  • ab
[a-z]{2} abacad
  • ab
  • ac
  • מודעה
AAA aaaaa
  • AAA
[a-z]/ a/b/c/d/e
  • a/
  • b/‎
  • c/‎
  • d/‎
/[^/]+/ aa/bb/cc
  • /bb/
[0-9]+‎ abc
(?:/?)[a-z] /abc
  • /abc
(?:/)[a-z] /abc
  • /abc
(?:[0-9]abc){3}(?:[a-z]000){2} 7abc7abc7abcx000y000
  • 7abc7abc7abcx000y000
".+" "חתולים" ו "כלבים"
  • "חתולים" ו "כלבים"


שימו לב שהשימוש במכמתים חמדניים + גורם להתאמה למחרוזת הארוכה ביותר האפשרית בטקסט, וכתוצאה מכך '"cats" and "dogs"' נשלף כאסימון בטקסט.
".+?" "חתולים" ו "כלבים"
  • "חתולים"
  • "כלבים"


שימו לב שהשימוש במכמתים עצלים +? גורם לביטוי הרגולרי להתאים למחרוזת הקצרה ביותר האפשרית בטקסט, וכתוצאה מכך הערכים '"cats"' ו-'"dogs"' נשלפים כשני אסימונים נפרדים בטקסט.

שימוש במנתח הטקסט PATTERN_ANALYZER נותן לכם יותר שליטה על האסימונים שחולצו מטקסט כשמשתמשים בפונקציה SEARCH. בטבלה הבאה מוצגות תוצאות שונות של SEARCH בהתאם לתבניות ולתוצאות שונות:

דוגמת קוד שאילתה טקסט טוקנים מטקסט SEARCH(text, query)‎ הסבר
abc abcdef abcghi
  • abcghi
TRUE ‫'abc' in ['abcghi']‎
cd[a-z] abcdef abcghi
  • abcghi
לא נכון 'cde' in ['abcghi']‎
[a-z]/ a/b/‎ a/b/c/d/
  • a/
  • b/‎
  • c/‎
  • d/‎
TRUE ‫'a/‎' ב-['a/‎', 'b/‎', 'c/‎', 'd/‎'] וגם 'b/‎' ב-['a/‎', 'b/‎', 'c/‎', 'd/‎']
/[^/]+/ aa/bb/‎ aa/bb/cc/
  • /bb/
TRUE ‫'/bb/' ב-['/bb/']
/[^/]+/ bb aa/bb/cc/
  • /bb/
שגיאה לא נמצאה התאמה במונח החיפוש
[0-9]+‎ abc abc123 שגיאה לא נמצאה התאמה במונח החיפוש
[0-9]+‎ `abc` abc123 שגיאה לא נמצאה התאמה במונח החיפוש

התאמה של גרש הפוך כגרש הפוך, לא כתו מיוחד.
[a-z][a-z0-9]*@google\.com כתובת האימייל שלי: test@google.com test@google.com
  • test@google.com
TRUE ‫'test@google.com' ב-'test@google.com'
abc abc\ abc abc
  • abc
TRUE ‫'abc' in ['abc']

חשוב לשים לב שהמחרוזת 'abc abc' היא שאילתת משנה אחת (כלומר) אחרי שהיא מנותחת על ידי מנתח שאילתות החיפוש, כי הרווח הוא תו בריחה.
‎(?i)(?:Abc)‎ (ללא נירמול) aBcd ABC
  • ABC
לא נכון 'aBc' in ['Abc']‎
‎(?i)(?:Abc)

normalization:
lower_case = true
aBcd ABC
  • abc
TRUE 'abc' in ['abc']‎
‎(?:/?)abc bc/abc /abc/abc/
  • /abc
TRUE ‫'‎/abc' ב-['‎/abc']
‎(?:/?)abc abc d/abc
  • /abc
לא נכון ‫'abc' ב-['‎/abc']
".+" "חתולים" "חתולים" ו "כלבים"
  • "חתולים" ו "כלבים"
לא נכון ‫'"cats"' in ['"cats" and "dogs"]

שימו לב שהשימוש בכמתים חמדניים + גורם לביטוי הרגולרי להתאים למחרוזת הארוכה ביותר האפשרית בטקסט, וכתוצאה מכך '"cats" and "dogs"' נשלף כאסימון בטקסט.
".+?" "חתולים" "חתולים" ו "כלבים"
  • "חתולים"
  • "כלבים"
TRUE ‫'"cats"' in ['"cats"', '"dogs"]

שימו לב שהשימוש במכמתים עצלים +? גורם לביטוי הרגולרי להתאים למחרוזת הקצרה ביותר האפשרית בטקסט, וכך '"cats"', '"dogs"' מחולצים כשני אסימונים נפרדים בטקסט.

דוגמאות

בדוגמאות הבאות מוסבר איך להשתמש בניתוח טקסט עם אפשרויות התאמה אישית כדי ליצור אינדקסים של חיפוש, לחלץ אסימונים ולהחזיר תוצאות חיפוש.

LOG_ANALYZER עם נרמול NFKC ICU ומילות עצירה

בדוגמה הבאה מגדירים אפשרויות של LOG_ANALYZER עם נורמליזציה של NFKC ICU ומילות עצירה. בדוגמה הזו, טבלת הנתונים כבר מאוכלסת בנתונים:

CREATE TABLE dataset.data_table(
  text_data STRING
);

כדי ליצור אינדקס חיפוש עם נרמול NFKC ICU ורשימה של מילות עצירה, יוצרים מחרוזת בפורמט JSON באפשרות analyzer_options של הצהרת ה-DDL של CREATE SEARCH INDEX. הרשימה המלאה של האפשרויות שזמינות כשיוצרים אינדקס חיפוש באמצעות LOG_ANALYZER מופיעה במאמר LOG_ANALYZER. בדוגמה הזו, מילות העצירה הן "the", "of", "and", "for".

CREATE OR REPLACE SEARCH INDEX `my_index` ON `dataset.data_table`(ALL COLUMNS) OPTIONS(
  analyzer='PATTERN_ANALYZER',
  analyzer_options= '''{
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFKC",
          "icu_case_folding": true
        }
      },
      { "stop_words": ["the", "of", "and", "for"] }
    ]
  }''');

בהתאם לדוגמה הקודמת, בטבלה הבאה מתואר חילוץ האסימונים לערכים שונים של text_data. שימו לב שבמסמך הזה, תו סימן השאלה הכפול (⁇) מופיע בכתב נטוי כדי להבדיל בינו לבין שני סימני שאלה (??):

טקסט של נתונים טוקנים לאינדקס הסבר
The Quick Brown Fox ["quick", "brown", "fox"] הטוקניזציה של LOG_ANALYZER יוצרת את הטוקנים ["The", "Quick", "Brown", "Fox"].

לאחר מכן, נורמליזציה של ICU עם icu_case_folding = true משנה את האסימונים לאותיות קטנות כדי ליצור את ["the", "quick", "brown", "fox"]

לבסוף, מסנן מילות העצור מסיר את "the" מהרשימה.
The Ⓠuick Ⓑrown Ⓕox ["quick", "brown", "fox"] הטוקניזציה של LOG_ANALYZER יוצרת את הטוקנים ["The", "Ⓠuick", "Ⓑrown", "Ⓕox"].

לאחר מכן, נורמליזציה של NFKC ICU עם icu_case_folding = true ממירה את האסימונים לאותיות קטנות כדי ליצור את ["the", "quick", "brown", "fox"]

לבסוף, מסנן מילות העצור מסיר את "the" מהרשימה.
Ⓠuick⁇Ⓕox ["quick??fox"] הטוקניזציה של LOG_ANALYZER יוצרת את הטוקנים ["The", "Ⓠuick⁇Ⓕox"].

בשלב הבא, נורמליזציית NFKC ICU עם icu_case_folding = true ממירה את האסימונים לאותיות קטנות כדי ליצור את ["quick??fox"]. שימו לב שסימן השאלה הכפול ב-Unicode עבר נורמליזציה לשני סימני שאלה ב-ASCII.

לבסוף, המסנן של מילות עצירה לא עושה כלום כי אף אחד מהאסימונים לא נמצא ברשימת המסננים.

אחרי שיוצרים את אינדקס החיפוש, אפשר להשתמש בפונקציה SEARCH כדי לחפש בטבלה באמצעות אותן הגדרות של מנתח שצוינו באינדקס החיפוש. שימו לב שאם הגדרות המנתח בפונקציה SEARCH לא תואמות להגדרות של אינדקס החיפוש, לא ייעשה שימוש באינדקס החיפוש. משתמשים בשאילתה הבאה:

SELECT
  SEARCH(
  analyzer => 'LOG_ANALYZER',
  analyzer_options => '''{
    "token_filters": [
      {
        "normalizer": {
          "mode": "ICU_NORMALIZE",
          "icu_normalize_mode": "NFKC",
          "icu_case_folding": true
        }
      },
      {
        "stop_words": ["the", "of", "and", "for"]
      }
    ]
  }''')

מחליפים את מה שכתוב בשדות הבאים:

  • ‫search_query: הטקסט שרוצים לחפש.

בטבלה הבאה מוצגות תוצאות שונות על סמך טקסט חיפוש שונה וערכים שונים של search_query:

text_data search_query תוצאה הסבר
The Quick Brown Fox "Ⓠuick" TRUE הרשימה הסופית של הטוקנים שחולצו מהטקסט היא ["quick", "brown", "fox"].
הרשימה הסופית של האסימונים שחולצו משאילתת הטקסט היא ["quick"].

כל טוקני השאילתה של הרשימה נמצאים בטוקני הטקסט.
The Ⓠuick Ⓑrown Ⓕox "quick" TRUE הרשימה הסופית של הטוקנים שחולצו מהטקסט היא ["quick", "brown", "fox"].
הרשימה הסופית של האסימונים שחולצו משאילתת הטקסט היא ["quick"].

כל טוקני השאילתה של הרשימה נמצאים בטוקני הטקסט.
Ⓠuick⁇Ⓕox "quick" FALSE הרשימה הסופית של הטוקנים שחולצו מהטקסט היא ["quick??fox"].

הרשימה הסופית של האסימונים שחולצו משאילתת הטקסט היא ["quick"].

המילה "quick" לא נמצאת ברשימת האסימונים מהטקסט.
Ⓠuick⁇Ⓕox "quick⁇fox" TRUE הרשימה הסופית של הטוקנים שחולצו מהטקסט היא ["quick??fox"].

הרשימה הסופית של האסימונים שחולצו משאילתת הטקסט היא ["quick??fox"].

"quick??fox" נמצא ברשימת הטוקנים מהטקסט.
Ⓠuick⁇Ⓕox "`quick⁇fox`" FALSE ב-LOG_ANALYZER, תג חצוי דורש התאמה מדויקת של הטקסט.

‫PATTERN_ANALYZER לחיפוש IPv4 עם מילות עצירה

בדוגמה הבאה, מנתח הטקסט PATTERN_ANALYZER מוגדר לחפש דפוס ספציפי תוך סינון של מילות עצירה מסוימות. בדוגמה הזו, התבנית תואמת לכתובת IPv4 ומתעלמת מהערך של המארח המקומי (127.0.0.1).

בדוגמה הזו, אנחנו מניחים שהטבלה הבאה מאוכלסת בנתונים:

CREATE TABLE dataset.data_table(
  text_data STRING
);

כדי ליצור אינדקס חיפוש עם האפשרות pattern ורשימה של מילות עצירה, יוצרים מחרוזת בפורמט JSON באפשרות analyzer_options של הצהרת ה-DDL של CREATE SEARCH INDEX. הרשימה המלאה של האפשרויות שזמינות כשיוצרים אינדקס חיפוש באמצעות PATTERN_ANALYZER מופיעה במאמר PATTERN_ANALYZER. בדוגמה הזו, מילות העצירה הן הכתובת של המארח המקומי, 127.0.0.1.

CREATE SEARCH INDEX my_index
ON dataset.data_table(text_data)
OPTIONS (analyzer = 'PATTERN_ANALYZER', analyzer_options = '''{
  "patterns": [
    "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
  ],
  "token_filters": [
    {
      "stop_words": [
        "127.0.0.1"
      ]
    }
  ]
}'''
);

כשמשתמשים בביטויים רגולריים עם analyzer_options, צריך לכלול שלושה סמלי \ בתחילת הביטוי כדי להוסיף תו בריחה (escape) לביטויים רגולריים שכוללים את הסמל \, כמו \d או \b.

בטבלה הבאה מתוארות אפשרויות הטוקניזציה לערכים שונים של text_data

טקסט של נתונים טוקנים לאינדקס הסבר
abc192.168.1.1def 172.217.20.142 ["192.168.1.1", "172.217.20.142"] התבניות של IPv4 מתעדות את כתובות ה-IPv4 גם אם אין רווח בין הכתובת לטקסט.
104.24.12.10abc 127.0.0.1 ["104.24.12.10"] הכתובת "127.0.0.1" מסוננת כי היא נמצאת ברשימת מילות העצירה.

אחרי שיוצרים את אינדקס החיפוש, אפשר להשתמש בפונקציה SEARCH כדי לחפש בטבלה על סמך הטוקניזציה שצוינה ב-analyzer_options. משתמשים בשאילתה הבאה:

SELECT
  SEARCH(dataset.data_table.text_data
  "search_data",
  analyzer => 'PATTERN_ANALYZER',
  analyzer_options => '''{
    "patterns": [
      "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
      ],
    "token_filters": [
      {
        "stop_words": [
          "127.0.0.1"
        ]
      }
    ]
  }'''
);

מחליפים את מה שכתוב בשדות הבאים:

  • ‫search_query: הטקסט שרוצים לחפש.

בטבלה הבאה מוצגות תוצאות שונות על סמך טקסט חיפוש שונה וערכים שונים של search_query:

text_data search_query תוצאה הסבר
128.0.0.2 "127.0.0.1" שגיאה אין אסימון חיפוש בשאילתה.

השאילתה עוברת דרך מנתח הטקסט, שמסנן את האסימון "127.0.0.1".
abc192.168.1.1def 172.217.20.142 "192.168.1.1abc" TRUE רשימת הטוקנים שחולצו מהשאילתה היא ["192.168.1.1"].

רשימת הטוקנים שחולצו מהטקסט היא ["192.168.1.1", "172.217.20.142"].
abc192.168.1.1def 172.217.20.142 "`192.168.1.1`" TRUE רשימת הטוקנים שחולצו מהשאילתה היא ["192.168.1.1"].

רשימת הטוקנים שחולצו מהטקסט היא ["192.168.1.1", "172.217.20.142"].

חשוב לזכור שהתגים האחוריים נחשבים לתווים רגילים ב-PATTERN_ANALYZER.

המאמרים הבאים