none
ספרות ב FULLTEXT SEARCH RRS feed

  • שאלה

  • שלום לכולם

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

    contains (col1, '5088')

    אני מקבל את כל השורות שהעמודה COL1 מסתיימת במחרוזת '5088', אולם אם אני מנסה לחפש את המחרוזת '088', אני לא מקבל שום שורה.
    ניסיתי עם CHARINDEX אך הביצועים היו גרועים.

    כל רעיון יתקבל בתודה

    אריה


    אריה שטרן

    יום שני 16 ינואר 2017 15:25

כל התגובות

  • אהלן אריה

    FTS במהות שלו (ולכן בתכנון שלו) נועד לביצוע פעולות חיפוש מורפולוגיות - ז"א חיפוש מבוסס שפה ותוכן. הוא לא נועד לביצוע חיפוש של מספרים שאין להם משמעות מורפולוגית, במקור.

    למרות מה שכתבתי מעל לפעמים FTS הוא הפתרון הנכון גם לחיפושים "רגילים" מכיוון שהוא יוצר לנו את האינדקס החיפוש הייחודי שלו.

    היה יכול מאוד לעזור אם היית מספק לנו DDL+DML כאשר אתה שואל שאלה בפורום, כדי לזרז את העזרה תוך הדגמה מתאימה. אני ממתין כרגע לחידוש החשבון AZURE שלי ואין לי את המכונות הוירטואליות של המשחקים במצב דלוק אז הנה תיאוריה שאמורה לעזור:

    הערה כללי: במבט ראשוני ניראה שיש צורך לבצע חשיבה מחודשת על תכנון מסד הנתונים. שמירת מספרים בטור טקסטואלי הוא אחד הדברים הכי איומים שיכולים להיות בתכנון מסד נתונים, בדרך כלל. במבט ראשוני ורק לפי ההתרשמות הראשונית נראה ש FTS הוא כניראה לא הכיוון האידאלי עבורכם. (1) מדובר בטור קצר מאוד של 10 תווים בלבד (דרך אגב בטבלה יש טורים ולא שדות - שדה זה מה שיש לנו בטופס באפליקציה למשל), (2) אתם מחפשים ערכים מדוייקים ולא ערכים מורפולוגיים, ו(3) מדובר בערכים מספריים במהות.

    אז מה השלב הבא ומה אפשר לעשות:

    א. עם זה כאמור לעיתים זה פתרון טוב שיכול להתאים לארכיטקטורה של מסד הנתונים. במקרה כזה צריך לזכור ש FTS תלוי בשפה מסויימת ובחוקי שפה (חבל שלא היה לי עוד כמה שעות להרצאה של אלמנטים לא דטרמיניסטים מכיוון שלא הספקתי לדבר על FTS בכלל והכל נסנ לקטגוריה שלנו) וחשוב לזכור שהוא תלוי ב stop list

    אתה יכול לבדוק את ההתנהגות כאשר אתה מנטרל את ה Stop list או שאתה יכול לנסות להגדיר רשימה שלך ולעבוד איתה.

    הנה כמה שאילתות שיכולות לעבוד בניהול ה Stop List

    -- Query stopwords
    select * from sys.fulltext_stopwords
    -- Query stop lists
    select * from sys.fulltext_stoplists
    -- Check what words included in the catalog
    SELECT * FROM sys.dm_fts_index_keywords(DB_ID('dbname'), OBJECT_ID('tablename'))
    -- Check the association
    select fulltext_catalog_id,stoplist_id, * from sys.fulltext_indexes;
    -- Turn stoplist off:
    ALTER FULLTEXT INDEX ON CremeSearchFT SET STOPLIST = OFF

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

    ג. טיפ מבית היוצר של רונן :-)

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

    למשל אנחנו רציכים לשמור את הערך 0001 ולכן אם נשתמש בטור מספרי הרי שנקבל רק את הערך 1 ולא נדע כמה אפסים מקדימים היו לנו.

    1. אם האורך של הטקסט תמיד קבוע ז"א מספר האפסים נועד להשלים את האורך, אז יש להישתמש בטור מספרי פשוט וברמת האפליקציה/שאילתה לבצע את ההלמה לאורך הנכון. למשל אם אנחנו יודעים שהערך צריך להיות תמיד 4 ספרות ואנחנו מקבלים 1 אז ברור שערך הנכון הוא 0001.

    2 המקרה היותר מורכב במבט ראשוני הוא כאשר האורך לא ידוע. ז"א לפעמים רוצים לשמור את הערך 0001 ולפעמים את הערך 01.

    הפתרון: 2 טורים מספריים. הטור הראשון יכיל את המספר ללא האפסים המקדימים ויהיה מסוג מתאים לערכי המספרים, והטור השני יכול להיות פשוט tinyint ויכיל את האורך השרשרת שלנו. כך שמברה של 0001 הטור השני יכול את הערך 4 ובמקרה של 01 הוא יכל את הערך 2.

    בצורה זו אפשר להגיע למיטוב ביצועים ניכר מאוד בהשוואה לעבודה עם טור טקסטואלי


    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]    [Linkedin]


    יום שלישי 17 ינואר 2017 13:51
    מנחה דיון