بعد تخرجه من المرحلة الثانوية، وبعد انتظار طويل من اجل الحصول على وظيفة، التحق "عبود اللوح" في إحدى شركات الاتصالات لمص الأموال، وبحكم ضعف شهادته وقلة خبرته العملية لم يجد أي فرصة في الشركة سوى العمل في قسم استعلامات الدليل، وبسبب غباء المبرمجين وعدم بنائهم لنظام ذا جودة عالية، لنرى ماذا حدث مع عبود في يومه الأول! ترن ترن .. ترن ترن [متصل] عبود: عبود اللوح من شركة الاتصالات لمص الأموال .. كيف اقدر أخدمك؟ المتصل: نعم .. أريد منزل محمد المحمد ___أدخل عبود الاسم Mohammed ولم تظهر نتيجة (فالاسم مخزن في قاعدة البيانات Mohammad). عبود: معذرة يا اخي الكريم ولكن الاسم غير موجود. المتصل: معقولة! حسنا لا مشكلة .. شكرا لك... عبود: العفو طووط طووط طووط طووط ترن ترن .. ترن ترن [متصل] عبود: عبود اللوح من شركة الاتصالات لمص الأموال .. كيف اقدر أخدمك؟ المتصل: عباس السريع لو سمحت ___كتب عبود الاسم Abas ولم تظهر نتيجة (فالاسم مخزن في قاعدة البيانات Abbas) عبود: معذرة يا اخي الكريم ولكن الاسم غير موجود. المتصل: نعم! يا ابن الناس انا متأكد انه موجود... عبود: صدقني يا أخي الكريم .. الشخص غير موجود، يرجى التأكد من الاسم و... المتصل [مقاطعا] : أقول... عبود: هلا طووط طووط طووط طووط (أقفل الخط في وجهه) ترن ترن .. ترن ترن [متصلة] عبود: عبود اللوح من شركة الاتصالات لمص الأموال .. كيف اقدر أخدمك؟ المتصلة: واحد صحن مشاوي.. اثنين عصير .. و .. عبود [مقاطعا] : معذرة يا اختي الكريمة .. هذه شركة اتصالات وليس مطعم! المتصلة: اها .. اسفة .. اريد رقم مطعم السعادة لطلبات توصيل منازل التعاسة. ___كتب عبود الاسم Saadah ولم تظهر نتيجة (فالاسم مخزن في قاعدة البيانات Saada) عبود: معذرة يا اختي ولكن الرقم غير موجود! المتصلة: كيف تقول غير موجود! طلبت منه الاسبوع الماضي وكان صحيح؟ عبود: صدقيني غير موجود ويمكنك الطبخ في بيتك هذه المرة! المتصلة: نعم! وشو دخلك أنت؟ ومن أنت عشان تحدد لي متى اطبخ ومتى اطلب؟ عبود: معذرة يا سيدتي ولكن كانت مجرد مزحة! المتصلة: بالفعل انت شخص قليل ذوق وراح ارفع شكوى عليك! عبود: يا سيدتي معذرة ولكن .. طووط طووط طووط طووط ترن ترن .. ترن ترن [متصل] عبود: عبود اللوح من شركة الاتصالات لمص الأموال .. كيف اقدر أخدمك؟ المتصل: تركي عبود: لا أنا سعودي! المتصل: ها ها ها .. أقصد تركي العسيري لو سمحت. ___ كتب عبود الاسم Turky ولم تظهر نتيجة (فالاسم مخزن في قاعدة البيانات Turki) عبود: معذرة يا اخي الكريم ولكن الاسم غير موجود. المتصل: يا اخي هذا الشخص رقمه مسجل في شركتكم انا متأكد، ويمكن زيارة موقع al-asiri.COM حتى تصدق؟ عبود: مصدقك ولكنه غير موجود، ليش ما تراسله عن طريق موقعه؟ المتصل : نعم نعم نعم! وش رأيك تجي تعلمني النت أحسن! لو كان عندي اتصال بالشبكة حاليا ما طلبت رقمه من عندكم طووط طووط طووط طووط ترن ترن .. ترن ترن [متصلة] عبود: عبود اللوح من شركة الاتصالات لمص الأموال .. كيف اقدر أخدمك؟ المتصلة: أنا الجميلة!! عبود: عفوا! المتصلة: أنا الجميلة! [بصوت أعلى] عبود: معذرة يا اختي، ولكن هذه المكالمة مسجلة وهذه شركة محترمة و... المتصلة [مقاطعة] : الله يشفيك يالمريض! اقصد مشغل "أنا الجميلة" النسائي! عبود: اها المعذرة.. لحظة لو سمحتي. ___كتب عبود الاسم Jameela ولم تظهر نتيجة (فالاسم مخزن في قاعدة البيانات Gameela) عبود: اسف واعتذر بشدة ولكن الرقم غير موجود. المتصلة: يا اخي المشغل موجود وفستاني عندهم .. كيف تقول غير موجود! عبود: حاولت البحث عنه ولكن يبدو انه غير مخزن في قاعدة البيانات. المتصلة : انت الذي بحاجة إلى قاعدة بيانات في عقلك .. وما ادري كيف يوظفون هذه الأشكال؟! طووط طووط طووط طووط ترن ترن .. ترن ترن [متصل] عبود: عبود اللوح من شركة الاتصالات لمص الأموال .. كيف اقدر أخدمك؟ المتصل: امممم اممم اااه .. معذرة غلطان ! طووط طووط طووط طووط استمرت الاتصالات على عبود اللوح ولم يستطيع خدمة الغالبية الساحقة منها بحجة (عدم وجودها في قاعدة البيانات)، وزادت شكاوي العملاء على هذا المسكين حتى تم فصله من وظيفته التي كانت فرصته المهنية الوحيدة. من هو المذنب؟ في الحقيقة الذنب ليس ذنب عبود اللوح فقد كان مخلصا في عمله وحاول البحث في قاعدة البيانات ولكن اختلاف الإملاء Spelling هو السبب، والذنب (في رأيي) هو ذنب فريق التطوير الذي صنع برنامج دليل الاستعلام، فلم يعتمدوا على خوارزم البحث الصوتي SOUNDEX Algorithm، والذي ظهر منذ الإصدار SQL Server 2000. تقتضي فكرة هذا الخوارزم بالبحث عن الكلمات في السجلات الحرفية للجدول بناء على نطقها الصوتي Phonic Pronunciation، وذلك عن طريق محاولة ايجاد الكلمة المشابهة في نطقها الكلمة المراد البحث عنها، يفيد كثيرا (هذا الخوارزم) عند البحث عن الأسماء Names وذلك لأن صيغة كتابة الأسماء غير موحدة عالميا، ويختلف هجائها وإملائها من شخص إلى آخر، فعندما نريد البحث عن الاسم Turki لن تظهر الا السجلات التي تحتوي علي الاسم Turki كما كتب تماما، ولكن -وعند تطبيق خوارزم البحث الصوتي- فإن البحث عن الاسم Turki سيظهر جميع هذه النتائج: Turki Turky Turkey Torki Torky Torkey فهم الخوارزم حتى تبدأ باستخدام خوارزم البحث الصوتي مع الخادم SQL Server، كل ما تحتاجه استخدام الدالتان SOUNDEX و DIFFERENCE مع جمل الاستعلام SQL، أستطيع ان افجر امام عينيك مثال لاستخدامهما وأرتاح من عناء كتابة المقال، ولكني فضلت شرح فكرة الخوارزم أولا حتى تتمكن من التعامل مع الدالتين بشكل أكثر اعتمادية. استخدام الدالة SOUNEX الغرض من الدالة SOUNDEX تحويل الكلمة (المخزنة في السجل) إلى قيمة خاصة، تتكون هذه القيمة الخاصة من 4 خانات، الخانة الأولى هي الحرف الأول من الكلمة الأصلية، والخانات الثلاث المتبقية عبارة عن أرقام تمثل النطق الصوتي، فعند تطبيق –مثلا- الدالة SOUNDEX على الكلمة Turki ستتحول إلى القيمة T620. لأغراضك الإختبارية، قد تود معرفة القيم التي ستتحول لها الكلمات بعد تطبيق الدالة SOUNDEX عليها، يمكن معرفة ذلك بسهولة شديدة جدا، حيث كل ما عليك فعله هو استخدام اسم الدالة SOUNDEX وارسل اليها اسم الحقل التي تود تطبيق الخوارزم عليه، بافتراض ان اسم الحقل هو FirstName الموجود في الجدول NamesTable، قد تخرج اناملك شيئا مثل: SELECT FirstName, SOUNDEX(FirstName) AS SoundTest FROM NamesTable وقد تكون المخرجات شبيه بـ: الدالة DIFFERENCE يبدو أن سر اللعبة بدأ بالانكشاف، فقد فهمنا ان الدالة SOUNDEX تقوم بتحويل الاسم إلى قيمة مكونة من 4 خانات، والان يأتي دور الدالة DIFFERENCE والتي تقوم بحساب الفرق بين قيمتين ومن ثم تعتمدها او لا، يمكنك إرسال القيمة التي تود اختبارها كوسيط ثانية للدالة: SELECT FirstName, SOUNDEX(FirstName) AS SoundTest, DIFFERENCE(FirstName, 'Turki') As DiffTest FROM NamesTable الاضافة السابقة ستظهر حقل جديد (بالاسم DiffTest) يظهر فرق القيم عن الكلمة "Turki" كما بالشكل التالي: تلاحظ في الشكل السابق نتائج حساب الفرق بالدالة DIFFERENCE مع الاسم Turki، حيث كان الفرق 4 عند الاسماء التي تشبه Turki وقل كثيرا مع الاسماء الاخرى، وحتى تتحكم اكثر في عملية الفلترة لاحقا، عليك معرفة كيف تحسب نتيجة الفرق. عندما تستخدم الدالة DIFFERENCE(x, y) ستعود بقيمة تمثل مستوى الفرق الصوتي بين الكلمة x و الكلمة y، نتيجة هذه القيمة تكون بين 0 إلى 4، الرقم 4 يشير بأن الكلمتان x و y متشابهتان جدا بينما القيمة 0 تشير إلى عدم وجود أي تشابه صوتي بينهما، طريق حساب الفرق تكون كالتالي: 1. يتم تحويل الكلمة x إلى القيمة الصوتية sx (والتي تتكون من اربع خانات باستخدام SOUNDEX). 2. يتم تحويل الكلمة y إلى القيمة الصوتية sy. 3. اذا كان جميع خانات القيمة sx تماثل خانات القيمة sy فستعود الدالة DIFFERENCE بالقيمة 4، وتنتهي المقارنة. 4. ان كانت الخانة الأول لـ sx لا تساوي الخانة الأولى لـ sy فستكون النتيجة الابتدائية 0. 5. يتم مقارنة الخانة الثانية لكلا القيمتين، ان توافقا زادت النتيجة بواحد، وان لم يتوافقا تتم مقارنة القيمة الثالثة ... وهكذا. وقت العرض Show Time لست متأكدا إن كنت فهمت طريقة حساب الفرق ام لا، ولكن استيعابك لها يعتبر بالغ الاهمية حتى تظهر نتائج اكثر دقة، فلو اردنا تطبيق الفلترة ورغبنا بالبحث عن الاسم Khaled، قد نكتب: SELECT FirstName FROM NamesTable WHERE DIFFERENCE(FirstName, 'Khalid') = 4 لتكون النتيجة: تلاحظ في الشرط السابق اني طلبت ان يكون الفرق 4 (متشابهة تماما)، ولكن في حالات كثيرة (خاصة ان وجد اختلاف في الحرف الأول) يفضل تقليص الفرق إلى 3، فلو كنا نبحث عن الاسم "قاسم" فهناك من يكتبه Kasem وهناك من يكتبه Qasem: SELECT FirstName FROM NamesTable WHERE DIFFERENCE(FirstName, 'Qasem') >= 3 لست بحاجة لأخبرك بأنك كلما قلصت الفرق كلما اصبحت النتائج اكثر تباعدا! (1) لا تتحمس كثيرا!! قد يكون شد انتباهك هذا الخوارزم كثيرا وأثار شهوتك البرمجية، وقد تنوي الاعتماد عليه في ((كل)) جملة استعلام ينطق بها برنامجك القادم، ولكن اتمنى ان تطفئ لهيب الحماس قليلا وتنظر إلى الوجه المظلم من هذا الخوارزم! قلت في بداية هذا المقال ان الخطوة الاولى التي يفعلها الخوارزم (بالتحديد الدالة SOUNDEX) هي تحويل الكلمات إلى قيم صوتية خاصة مكونة من 4 خانات، وقد تسألني سؤال وتقول ماهي القاعدة او ما هو الاساس الذي بنت عليه الدالة SOUNDEX لتوليد هذه القيم؟ والاجابة لست مضطرا لمعرفتها (بكل أمانة لم أتعمق في هذه المسألة كثيرا ولا أدري كيف ولدت)، ولكنك مضطر لمعرفة بضعة أمور خطيرة جدا حول هذه العملية، اولها (كما سبق ذكره) ان الخانة الأولى تكون الحرف الأول من الكلمة. بخصوص الأرقام، فيتم توليدها بناء على حروف الكلمة الأصلية، ولكن عليك معرفة ان الدالة SOUNDEX تقوم بتجاهل حروف العلة Vowel Letters الانجليزية (a e i o u) بالاضافة إلى الحرفين h و y، مع العلم ان الحرف الأول لا يتم تجاهله حتى لو كان حرف علة، فالاسم Ahmed يعطي القيمة A530 بعد تحويله. المزيد أيضا، بعد تجاهل حروف العلة تبدأ الدالة بفهم حرف حرف من الاسم، وبمجرد وجود مسافة او رقم او أي رمز أخر غير الحروف سيتم تجاهل باقي الحقل، فالاسم Al-Asiri يعطي القيمة A400 والاسم Al-Qahtani يعطي القيمة A400 ايضا، والسبب ان الدالة اختبرت الحروف Al فقط (والتي دائما تعطي القيمة A400). (2) في حالة كون جميع الحروف التي تلي الحرف الأول هي حروف علة (او من ضمن الحروف المتجاهلة) مثل الاسم Maya، فسيتم تجاهلها كما ذكرت وتصفيرها لتعطي القيمة M000. المزيد من العيوب ايضا، تقوم الدالة بتحويل 3 حروف (ثابتة Constant غير العلة) من بعد الحرف الأول للكلمة فقط، وان وجد اكثر فلا تؤخذ بعين الاعتبار، فالاسماء Abdullah و Abdullrahman تعودان بالقيمة A134. كما ان الدالة SOUNDEX ليست صوتية بشكل واقعي، فهي –مثلا- لا تميز الحروف الساكنة Silent Letters، فالكلمة Knife تعطي القيمة K510 بينما (اختها في النطق) Nife تعطي القيمة N100. اخيرا (معذرة على التطفيش)، الارقام المولدة لا تفرق بين الحرفان m و n، نطق الاسماء Smeef و Snaaf يبدوان مختلفان كثيرا، ولكن مع الجانب المظلم للدالة SOUNDEX، كلامها يعطي القيمة S510! (احذف حروف العلة وستفهم السبب). ألهذه الدرجة هي سيئة؟ في الحقيقة ليست سيئة بل على العكس من ذلك فهي مفيدة جدا (على الاقل ستعطي نتائج اضافية مع عملية البحث)، ولكن (من واقع خبرتي الشخصية) انصحك بالاعتماد عليها عند حالات كون الكلمات غير موحدة الهجاء مثل الاسماء، او يمكنك جعل برنامجك يدعمها كخدمة او خيار اضافي للمستخدم، فهي ان لم تفيده لن تضره. عرضت في هذا المقال اسلوب البحث الصوتي والذي يدعمه SQL Server منذ اصداره 2000، أتمنى من جميع المبرمجين ((مساعدة)) و ((تسهيل)) حياة المستخدمين فهم استخدموا انظمتنا لمساعدتهم في حل مشاكلهم وليس زيادتها، كما ارجوا من شركة الاتصالات اعادة عبود اللوح إلى مكان عمله فالذنب ليس ذنبه! -- تركي ________________________ (1) سيكون من الرائع اعطاء فرصة لمستخدم برنامجك امكانية تعديل قيمة الفرق. (2) نفهم انها لا تصلح للاستخدام مع الحقول التي تحتوي على اكثر من كلمة.