من أهم الميزات التي يجب أن يتمتع بها أي موقع ويب اخباري هو محرك البحث الذي يحتويه الموقع. عندما يريد المستخدم طرح سؤال أو البحث على مقال محدد فلا بد أن يقوم بالعملية بطريقة سريعة و دقيقة في نفس الوقت.
الأمر sql على كامل النص يعتبر حلا سريعا و سهلا و لكن لا يعتبر بتاتا الحل الأمثل من ناحية الفعالية من جهة و من جهة ثانية أن الأمر ليس بالسهل لكتابة محرك بحث بواسطة الأوامر sql.
هذا المقال سيعطيكم لائحة لمجموعة من محركات البحث التي يمكنكم تثبيتها على خادم الويب الخاص بموقعكم. بالاضافة للAPI روبي التي تقوم بذلك.
في هذا المقال أردت أن أعرفكم عن أحد لغات البرمجة التي أحببتها و لا زلت أحبها كيف لا و قد كانت رفيقتي قبل الجافا في تسهيل مهامي في مجال البحث العلمي، إنها لغة بيرل Perl.
لغة Perl : Practical Extracting and Reporting Language هي كما قلت لغة برمجة أنشأها Larry Wall في عام 1987 مدرجا ميزات عديدة للغة الc و لغات سكريبت كالsed و الawk لينوكس اللغة أنشأت في الأصل للتعامل بسهولة مع الملفات و السلاسل.
في هذا المقال الجديد و الذي من خلاله أفتح صفحة جديدة و نوعا آخر من المقالات أبدأ الكتابة في مجال البحث العلمي الخاص بعلم الحاسوب في المجال الطبي من ناحية التعامل مع البيانات الطبية و تصنيفها و تحسين العمل و البحث فيها. في هذا المقال أبذأ بتعريف أكبر و أشهر قاعدة بيانات للمصطلحات الطبية الUnified Medical Language System أو الUMLS . بدأت به لأن الUMLS تعتبر أكبر إنجاز لحد الآن و الذي سهل بشكل كبير التعامل مع أغلب المصطلحات الطبية بجميع اللغات للآسف ماعدا اللغة العربية التي تعتبر شبه غائبة في هذا المجال الحساس و المهم.
→ أكمل القراءة
نحن بصدد تطوير تطبيق رايلز و نريد توزيع التطبيق للجميع، كما نريد من بياناتنا أن تشتغل على أكبر عدد ممكن من قاعدة البيانات تستطيع التعامل مع رايلز مثل MySQL،PostregSQL، SQLite، SQLServer و Oracle. بعبارة أخرى نريد تعريف لمخطط البيانات من غير التفكير في كيفية و طريقة كتابة الSQL.
قاعدة بيانات علائقية بدون تبادل مرجعي (cross-referencing) بين الجداول لا يعني الشيء الكثير. في مثال الجزء الأول المقال داخل المدونة (Post) يمكن أن يحوي على أكثر من تعليق أو لا يحوي أي تعليق. التعليق و الذي سيُمثل بجدول في قاعدة البيانات يحتوي على عمود (post_id) يُمكن من خلاله ربط التعليق بالمقال. الActiverecord يرعى هذه العلاقات بالنسبة لنا ويجعلها شفافة لحد كبير و لدرجة أننا لن نحتاج إلى لمس الSQL.
هناك مجموعة من العلاقات يستطيع الActiverecord إدارتها من بينها :
belongs_to :
تعتبر العلاقة الأكثر إستعمالا في قاعدة البيانات. قولنا بأن النوع أ ينتمي إلى النوع ب هذا يعني أن النوع أ يحتوي على عمود ID مرجعي للنوع ب. مثال ذلك، أنه داخل المدونة الPost يحتوي على أكثر من تعليق (Comments) أي بمعنى أخر أن التعليق ينتمي لPost واحد فهذا يعني أن الجدول الذي يمثل الComment سوف يحتوي على العمود Post_Id والذي يُشير إلى الPost الذي يحوي التعليق. النتيجة أنه إذا كان لك كائن يُمثل تعليقا من التعليقات (c) فإنه بإمكاننا إستخراج الPost الموافق عن طريق الأمر : c.Post و النتيجة أيضا أن حذف الPost يعني مباشرة حذف التعليقات التي تنتمي إليه.
has_many :
تُعبر العلاقة عن الطرف الأخر للعلاقة belongs_to. في المثال السابق كان بإمكاننا القول : التعليق ينتمي إلى مقال (belongs_to) أو المقال له مجموعة من التعليقات (has_many). المقال لا يحتفظ بجدول يحتوي على التعليقات التي تنتمي إليه، ولكن بكل بساطة يستعلم داخل جدول التعليقات و يستخرج تلك التي تتعلق به. فمثلا من أجل المقال p التعليقات الخاصة به ستُحفظ داخل جدول عن طريق الأمر : p.comments.
has_one :
هذه العلاقة تشبه إلى حد كبير العلاقة has_many، باستثناء أن العلاقة تربط بين كائنين فقط أي علاقة واحد-واحد. فمثلا داخل تطبيق، المستعمل له حساب واحد و واحد فقط في هذه الحالة نموذج المستعمل سيربط بالنموذج الخاص بالحساب بواسطة العلاقة has_one. وبالتالي العلاقة تفرض وحدانية الحساب الخاص بكل مستعمل أي أنه إذا أردنا مثلا إضافة
حساب آخر فهذا خطأ.
has_many :through Association :
تستعمل هذه العلاقة لإعداد العلاقة مجموعة إلى مجموعة (many to many) بواسطة نموذج وسط. العلاقة تشير إلى أن النموذج المعلن يمكن ربطه مع صفر أو أكثر من حالة لنموذج ثاني بواسطة نموذج ثالث وسط. لنفرض مثلا أننا نريد معرفة ثمن الحليب الذي يبيعه المربي لبائعي التجزئة. الأمر كان سهلا لو كان الثمن ثابت بحيث أنه كان بإمكاننا جعل ثمن الحليب عبارة عن عمود داخل الجدول الخاص بالمربي فقط ولكن هذا غير صحيح لأن الثمن غير ثابت و يختلف باختلاف بائعي التجزئة أو لأن البائع يشتري الحليب بأثمان مختلفة باختلاف المربين، في هذه الحالة يمكننا استعمال العلاقة has_many :through ، لأنه يجب تعريف نموذج وسط بين البائع و المربي يعبر عن عملية التوزيع DISTRIBUTION.
123456789101112
class Reseller < ActiveRecord::Base
has_many :distributions
has_many :farmers, :through => :distributions
end
class Distributions < ActiveRecord::Base
belongs_to :reseller
belongs_to :farmer
end
class Farmer < ActiveRecord::Base
has_many :distributions
has_many :resellers, :through => :distributions
end
has_and_belong_to_many :
هذه العلاقة تُعتبر مُعقدة نوع ما. المثال التقليدي هو “الوسمات”. بمعنى أن المقال له مجموعة من الوسمات و الوسام يمكن أن ينتمي إلى مجموعة مقالات مختلفة، أي أن العلاقة هي has_many بين الوسام و المقال بدون نموذج وسط.
الActiverecord يُمثل الطبقة المسؤولة عن تمثيل البيانات في رايلز. الActiverecord عرفه ووصفه مارتن فولر في كتابه “Patterns of Enterprise Application Architecture”. في الActiverecord، الكائنات (objects) توفر الحفظ الدائم للبيانات و كذلك التغيرات التي تطرأ على هذه البيانات.
الActiveRecord يُسهل إنشاء و إستعمال كائنات الأعمال التي تتطلب بيانات التخزين الثابتة من خلال قاعدة البيانات. إنه يُمثل نمط تصميم Activerecord والذي بدوره يصف نظام مخطط الكائن العلائقية ( object-relational mapping ) أو الORM، هذا الأخير عبارة عن تقنية تسمح بإيجاد علاقة بين الكائنات داخل تطبيق و جداول أنظمة تسيير قواعد البيانات. عمليا هذا يعني إستعمال الActiverecord لإنشاء و إستخراج البيانات بواسطة طرق وسِمات Ruby من دون الحاجة لاستعمال ال SQL بطريقة مباشرة. على سبيل المثال :
لنفرض أن تطبيقنا عبارة عن مدونة مكونة من مجموعة مقالات (يحتوي على نموذج نسميه Post) ونريد المقال
الأول، الطلب sql هو التالي :
1
SELECT * FROM posts ORDER BY date DESC LIMIT 1
باستعمال ال Activerecord الطلب يكون بالطريقة التالية و البسيطة :
1
p = Post.last
تلاحظون أن إستعمال الActiverecord يسهل عليكم التعامل مع البيانات و جعل الsql شفاف إلى حد كبير، في المثال السابق يمكنكم بكل بساطة إضافة عنوان بواسطة إستعمال الطريقة p.title بالطريقة التالية مثلا :
1
p.title = "dtmdeblog post"
CRUD :
CRUD هو مُختصر ل “CREATE, READ, UPDATE, DELETE” : العمليات الأربعة الأساسية داخل قاعدة البيانات. الActiveRecord يوفر كل هذه العمليات الأساسية بحيث أن كل عملية تتم مُعالجتها من قبل Ruby API إصطلاحية للغاية (idiomatic) :
CREATE :
لإنشاء كائن ActiveRecord و من تم تجسيد الإنشاء. على سيبل المثال : لو قمنا بإنشاء نموذج للمدونة إسمه Post داخل التطبيق، فإن إنشاء مقال يكون عن طريق كتابة الأمر : Post.new أو إذا أردنا إدخال كل
أو بعض الأوصاف للكائن يمكننا إستعمال الأمر create كالتالي :
1
Post.create \(title:”dtmdeblog post 1”, date:Time.now\)
READ :
تشير إلى استخراج البيانات من قاعدة البيانات. Activerecord يُوفر مجموعة من الطرق كاملة على شكل أسئلة باللغة الإنجليزية مثل : Post.last أو Post.first.
UPDATE :
التحديث عبارة عن عملية من عمليات القراءة (read) لكائن معين من قاعدة البيانات و من بعدها تبديل وصف أو مجموعة من الصفات ثم حفظ التغيير، على سبيل المثال، إذا أردنا تحديث المقال الذي يحمل العنوان “المقال الضادي” فإننا نقوم بإستخراج المقال المناسب بواسطة الطريقة :
1
p = Post.find_by_title(“dtmdeblog post 1”)
المقال الآن محفوظ داخل الكائن p. بعدها نقوم بتغيير العنوان كما لو أردنا إدخال عنوان جديد :
1
p.title = “dtmdeblog post new title”
و في الأخير لم يتبقى لنا سوى حفظ الكائن : p.save
DELETE :
هذا الفعل يُستعمل من أجل حذف الكائن و الذي يقوم بحذف سطر من داخل قاعدة البيانات بواسطة الأمر : DELETE.
في الجزء الثاني من المقال إن شاء الله سأقوم بشرح العلاقات التي يمكن إنشاءها بين الكائنات و كيف يُمكن إدارتها بالActiverecord
في هذا المقال الجديد و كبداية لتوجه جديد في مدونتي بالموازاة مع ماأكتبه عن روبي أون رايلز، قررت الكتابة عن Lucene. هذا التوجه له دافع مباشر في الحقيقة وهو طبيعة أعمالي في مجال البحث و التي تدور حول محرك بحث طبي، و طبيعة مذكرتي في الدكتوراه و التي دارت حول كل ما يتعلق بمجال المعالجة الآلية للغة و كل مايتعلق بالمكنزات الطبية. على كل حال دعوني أبدأ في مقالي المخصص لlucene و كما عودتكم من جانب تقني أكثر منه “صحفي”.
Lucene عبارة عن مكتبة برمجية مفتوحة المصدر مطورة بالجافا و متوفرة بلغات برمجة أخرى،
والهدف منه إضافة وظائف بحث و فهرسة داخل تطبيقاتكم. المشروع Lucene تتبناه The Apache Software Foundation. المكتبة لا تحتوي على أدوات يمكن إستعمالها مباشرة لفهرسة البيانات لهذا فإنه يجب المرور عبر البرمجة و الكود لوضع حجر
الأساس من أجل إنشاء محرك بحث داخل النصوص.
المبدأ :
Lucene يسمح بفهرسة الوثائق أو المستندات. المستندات عبارة عن مجموعة ملفات Excel, Word, PDF أو HTML, و لكن أيضا مجموعة من البيانات منظمة على مجموعة من الحقول. الحقل هو عبارة عن معطى يحتوي على إسم سواء كان هذا الإسم عنوان أو تاريخ النشر أو محتوى المعطى و الذي يُربط بنص، بحيث أن هذا النص هو الذي يُفهرس ثم نقوم بالبحث فيه. مجموعة النصوص تُجمع فيما بعد داخل مجموعة من النصوص تُسمى الفهرس. الفهرس يُمكن أن يحتوي على مئات، آلاف أو ملايين النصوص و يمكننا إنشاء عدد من الفهارس مختلفة حسب إختلاف الإحتياجات. فعليا، الفهرس عبارة عن ملف يقوم lucene بإنشاءه.
الحصول على Lucene و إستعماله:
النسخة الحالية هي النسخة 4.0 و هي متوفرة هنا. الملف من نوع .zip وهو يحتوي علي جميع المكتبات التي نحتاجها من أجل إستخدام مختلف الوظائف التي يقترحها. في باقي المقال سوف أعرض مثال مُبسط بالجافا حول كيفية إستخدام معظم الوظائف الرئيسية المتوفرة.
أول شيئ يُمكن القيام به هو إنشاء مشروع جديد و إدخال أهم المكتبات الرئيسية الموجودة التي تم الحصول عليها، شخصيا أستعمل Eclipse من أجل البرمجة بجافا و أستخدم أيضا النسخة 1.6 من جافا و لكن النسخة 1.5 يمكن إستعمالها من غير مشاكل.
من النظري إلى التطبيق :
المثال التالي عبارة عن مشروع مكون من فئة (class) واحدة فقط و لكن يمكن تقسيمه إلى قسمين فهرسة و بحث. قبل البدأ بسرد المثال أنوه أن البيانات التي سنقوم بتداولها عبارة عن أسطر بسيطة و لا تعبر عن بيانات من الحياة العملية و لكن كافية لتشغيل المثال.
فهرسة البيانات (Indexation) :
أول مرحلة يجب القيام بها هي تهيئة البيانات و إنشاء الفهرس للبحث عليه فيما بعد. من أجل ذلك فإن المكتبة توفر الفئات التي تسمح لنا بإنشاء الفهرس. أهم هذه الفئات هي الفئة IndexWriter و التي تسمح لنا بالتعامل مع الفهرس و الكتابة فيه : إنشاء الفهرس، إضافة مستند، … الفئة الأخرى هي الAnalyzer والتي تحتوي على الفئات التي تسمح بتقسيم النص إلى كلمات و من ثم تحديد ساق الكلمة، من أهم الفئات التي تُوفرها يمكن ذكر :
SimpleAnalyzer : يٌقسم النص إلى كلمات ثم يُحولها إلى شكلها المصغر.
StopAnalyzer : يٌقسم النص إلى كلمات، يُحولها إلى شكلها المصغر ثم يحذف الكلمات الفارغة أي الكلمات التي ليست لها فائدة كبيرة عند عملية البحث.
StandardAnalyzer : عبارة عن نسخة كاملة تحتوي علي خصائص الفئتين السابقتين.
فئة أخرى يمكن التنويه إليها هي الفئة Document و التي تمثل أصغر محتوى. على سبيل المثال، فهرسة كل الملفات Word داخل مجلد سيضيف إلى الفهرس Lucene مسند Document يُمثل كل ملف. وبالتالي لائحة النتائج التي يُرجعها البحث داخل الفهرس عبارة عن لائحة Documents. بدوره الDocument مُكون من ما نسميه Field أو الحقول و هي عبارة عن مجموعة فرعية من الDocument. الحقول المتداولة بكثرة هي : العنوان، المؤلف، تاريخ النشر …وهلم جر.
البحث (Search) :
البحث يستلزم إستعمال ستة فئات :
IndexSearcher : هي الفئة التي تسمح باستعمال فهرس البحث.
Analyzer : مثل الفهرسة فإن فئات تحليل النصوص يدخلن في عملية البحث من أجل تحليل الكلمات المستعملة في البحث.
QueryParser : من أجل تحليل كلمة البحث و تحويلها إلى سؤال مفهوم لLucene.
Query : عبارة عن كائن (object) يمثل سؤال المستخدم والذي سوف يستعمل من طرف IndexSearcher.
Hits : عبارة عن لائحة النتائج للبحث.
Hit : عضو من اللائحة.
و أخير الDocument والذي يمثل المسند كما تمت فهرسته.
في الأخير، لو تنجحون بتشغيل المثال : الفهرسة ثم البحث فإن النتيجة التي تُظهرها الشاشة عبارة عن كل الأسطر التي تمت فهرستها و التي تحتوي على الكلمة “lucene”.
ماهي السقالة أو الscaffolding في رايلز ؟ لشرح هذا المفهوم لنبدأ بطرح المشكل التالي :
أنت مطور و عندك فكرة لمشروع ما، قمت برسم المخطط لقاعدة البيانات و تريد إنشاء تطبيق بسيط و شغال بأسرع ما يمكن. الحل ب Ruby On Rails سهل :
بعد إنشاء قاعدة البيانات و ربط الإتصال بينها و بين رايلز، يمكنننا الطلب من رايلز إنشاء السقالة (scaffolding). إذا تمكنتم من ذلك فإنه يكون بحوزتكم تطبيق مُكون من وحدة تحكم و الكود من أجل الواجهة حتى يتم التواصل مع قاعدة البيانات. التطبيق شغال و لكن مُبسط لدرجة السماح لكم الإنطلاق بتطوير معمق لباقي التطبيق.
فيمايلي سأقوم بشرح تفصيلي للسقالة من خلال مثال بسيط. المثال عبارة عن تطبيق رايلز يحفظ مجموعة من لغات البرمجة مع تعريف مُختصر لكل لغة.
الخُطوة الأولى تكمن في تهيئة قاعدة البيانات، من أجل ذلك نقُوم بإنشاء سكريبت الmigration بواسطة الأمر التالي :
1
rails generate build_db $
الأمر ينشأ لنا الملف 20121223181308_build_db.rb في المجلد db/migrate داخل التطبيق. بعد فتح الملف يجب إضافة بعض الأسطر ليصبح كالتالي :
بعدها يجب تنفيذ السكريبت لإنشاء جدول لغات البرمجة داخل قاعدة البيانات :
1
rake db:migrate $
بعد إنشاء قاعدة البيانات يمكننا إنشاء السقالة عن طريق الأمر التالي :
1
rails generate scaffold languages$
كما توضح الصورة المٌرفقة، فإن الأمر ينشأ مجموعة من الملفات داخل شجرة المشروع و خاصة النموذج (model)، وحدة التحكم (controller) و مجموعة من ملفات الواجهة.
النتيجة أنه لدينا الآن تطبيق ويب شغال نستطيع الإعتماد عليه من أجل الذهاب بعيدا في مشروعنا النهائي.
في النهاية يجب التنويه أن المطورين في رايلز يرون في السقالة مجرد بوابة إنطلاق تساعد في تطوير الجزء الكبير للبرنامج. بالنسبة للمبتدئين مثلي، فإن السقالة تعتبر تدريب فعال لفهم طريقة إشتغال منصة رايلز. لا تنسو أن الواجهات المتحصل عليها يمكن تحسينها عن طريق ال CSS، فالواجهات المتحصل عليها لا يُستحسن تقديمها كما هي للمستخدمين النهائيين.