جدول المحتويات

نحو تطوير ثواب 3

الهدف من وراء ثواب هو عمل مشروع موسوعي عام يحتوي كل نتاج الأمة الفكري في شجرة وصف للمحتويات (بنيوية وليس ظاهرية) الكتب تقسم فيها إلى أبواب وفصول وفصول فرعية … ونص والمعاجم إلى معرِّف واحد والأحاديث إلى سند ومتن والسند إلى راوي وعلاقة (الراوي فلان العلاقة حدثني مثلا) وهكذا

فائدة التقسيم البنيوي للبيانات يتيح لنا مثلا إمكانية البحث في السند دون المتن أو إمكانية توليد شجرة الأسانيد تلقائيا

محدوديات ثواب 2

ثواب 2 صممت لتكون عارض لملفات الشاملة والتوافقية كانت هدف أي بطريقة bug for bug compatibility لأن أي تعديل في هيئة الشاملة تعني أن تنتظر فترة أطول حتى يتم استيراد الملف

الخطوة التالية هي استيراد الكتب بالكامل في صيغة مختلفة تماما تكون تمثيل هرمي فريد له مكافئ xml لمحتوى الكتاب وبنيته لا لشكل الكتاب ومظهره.

لكن في هذه الحالة يجب أن يقدم موقع أعجوبة كل الكتب بصيغة جاهزة دون استيراد

إلى ثواب 3

مصطلحات

محددات التصميم

مسألة للاختبار

الشكل المرفق شجرة محتويات عقدها عن الألوان فيها رقم الصف في قاعدة البيانات وعنوان العقدة.

المطلوب الأول: هو أن يتم استخراج جدول المحتويات مرتب بترتيب العمق أولا دون الاعتماد على أرقام الصفوف وأن يكون ذلك بإستعلام واحد

المطلوب الثاني: حشر اللون البرتقالي بين الأحمر والأصفر

المطلوب الثالث: حشر تمهيد قبل الباب الأول

المطلوب الرابع: تحويل التمهيد إلى باب به فصلان الإهداء والمقدمة

المطلوب الخامس: حشر باب الألوان المحايدة قبل الباب الأول

المطلوب السادس: تحويل باب الألوان الحارة والباردة إلى أبناء لباب ألوان الطيف

المطلوب السابع: نقل الأبيض إلى الألوان الحارة والأسود للباردة والتراجع عن ذلك

المطلوب الثامن: دمج الألوان الحارة والباردة لتكون فصولا في باب ألوان الطيف طبعا مع حذف الفصلين ثم إضافة بقية ألوان الطيف ثم التراجع عن كل هذا

مسألة عملية

من صحيح البخاري

حَدَّثَنَا يَعْقُوبُ بْنُ إِبْرَاهِيمَ قَالَ حَدَّثَنَا ابْنُ عُلَيَّةَ عَنْ عَبْدِ الْعَزِيزِ بْنِ صُهَيْبٍ عَنْ أَنَسٍ عَنْ النَّبِيِّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ ح و حَدَّثَنَا آدَمُ قَالَ حَدَّثَنَا شُعْبَةُ عَنْ قَتَادَةَ عَنْ أَنَسٍ قَالَ قَالَ النَّبِيُّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ لَا يُؤْمِنُ أَحَدُكُمْ حَتَّى أَكُونَ أَحَبَّ إِلَيْهِ مِنْ وَالِدِهِ وَوَلَدِهِ وَالنَّاسِ أَجْمَعِينَ

في الحديث سلسلتان بعد أنس

حَدَّثَنَا مُحَمَّدُ بْنُ عُبَيْدِ بْنِ مَيْمُونٍ حَدَّثَنَا عِيسَى بْنُ يُونُسَ عَنْ عُبَيْدِ اللَّهِ عَنْ نَافِعٍ عَنْ ابْنِ عُمَرَ رَضِيَ اللَّهُ عَنْهُمَا رَخَّصَ النَّبِيُّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ ح حَدَّثَنَا يَحْيَى بْنُ مُوسَى حَدَّثَنَا مُحَمَّدُ بْنُ بَكْرٍ أَخْبَرَنَا ابْنُ جُرَيْجٍ أَخْبَرَنِي عُبَيْدُ اللَّهِ عَنْ نَافِعٍ عَنْ ابْنِ عُمَرَ رَضِيَ اللَّهُ عَنْهُمَا أَنَّ النَّبِيَّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ أَذِنَ ح و حَدَّثَنَا مُحَمَّدُ بْنُ عَبْدِ اللَّهِ بْنِ نُمَيْرٍ حَدَّثَنَا أَبِي حَدَّثَنَا عُبَيْدُ اللَّهِ قَالَ حَدَّثَنِي نَافِعٌ عَنْ ابْنِ عُمَرَ رَضِيَ اللَّهُ عَنْهُمَا أَنَّ الْعَبَّاسَ رَضِيَ اللَّهُ عَنْهُ اسْتَأْذَنَ النَّبِيَّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ لِيَبِيتَ بِمَكَّةَ لَيَالِيَ مِنًى مِنْ أَجْلِ سِقَايَتِهِ فَأَذِنَ لَهُ تَابَعَهُ أَبُو أُسَامَةَ وَعُقْبَةُ بْنُ خَالِدٍ وَأَبُو ضَمْرَةَ

ملاحظات:

  1. روى هذا الحديث عن عبيد الله ستة من الرواة
  2. الحديث أتى بثلاثة ألفاظ
  3. انفرد راويي بلفظين مختلفين، واتفق أربعة على لفظ الذي ذكره البخاري بتمامه بينما لم يتم اللفظين السابقين
  4. إسناد البخاري إلى ابن جريج ومنه إلى النبي صلى الله عليه وسلم نازل (أي رجال السند أكثر) فبين البخاري وبين النبي صلى الله عليه وسلم في هذا الإسناد ستة من الرواة، وبينما في بقية الأسانيد خمسة.
  5. لم يذكر البخاري رحمه الله إسناده منه إلى ثلاثة من الرواة، وإنما اكتفى بقوله أن هؤلاء الثلاثة (أبو أسامة وعقبة وأبو ضمرة) تابعوا عبد الله بن نمير.
  6. ح تعني تحويل السند أي أن هذا فرع آخر من شجرة السند وهي تشبه قوع العوام ..إلخ حيث يذكر ذاك الجزء من السند ثم جزء من قول النبي صلى الله عليه وسلم
  7. من الضروري جدا إدخال صيغة التحمل عند تكوين شجرة الأسانيد (حدثنا تختلف عن سألت وتختلف عن “عن”)
  8. إن تم تمثيل الشجرة في الكتاب فإن الحصول على نص الكتاب يكون أصحب
  9. تاليا محاولة تسطيح الشجرة إلى سلاسل مع المحافظة على نفس النص الظاهر في الكتاب
<sanad>
<branch>
  <theCompiler/>
  <tahamul id="###">حدثنا</tahamul>
  <rawi id=XYZ>مُحَمَّدُ بْنُ عُبَيْدِ بْنِ مَيْمُونٍ</rawi>
  <tahamul id="###">حدثنا</tahamul>
  <rawi id=XYZ>عِيسَى بْنُ يُونُسَ عَنْ عُبَيْدِ اللَّهِ</rawi>
  <tahamul id="###">عن</tahamul>
  <rawi id=XYZ>عُبَيْدِ اللَّهِ عَنْ نَافِعٍ</rawi>
  <tahamul id="###">عن</tahamul>
  <rawi id=XYZ>ابْنِ عُمَرَ رَضِيَ اللَّهُ عَنْهُمَا</rawi>
  <tahamul id="###"/>
  <prophetMuhammad/>
  <phrasing>رَخَّصَ النَّبِيُّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ</phrasing>
  <shift/> <!-- rendered as ح //-->
</branch>
<branch>
  <theCompiler/>
  <tahamul id="###">حدثنا</tahamul>
  <rawi id=XYZ>يَحْيَى بْنُ مُوسَى</rawi>
  <tahamul id="###">حدثنا</tahamul>
  <rawi id=XYZ>مُحَمَّدُ بْنُ بَكْرٍ</rawi>
  <tahamul id="###">أخبرنا</tahamul>
  <rawi id=XYZ>ابْنُ جُرَيْجٍ</rawi>
  <tahamul id="###">أَخْبَرَنِي</tahamul>
  <rawi id=XYZ>عُبَيْدُ اللَّهِ عَنْ نَافِعٍ</rawi>
  <tahamul id="###">عن</tahamul>
  <rawi id=XYZ>ابْنِ عُمَرَ رَضِيَ اللَّهُ عَنْهُمَا</rawi>
  <tahamul id="###"/>
  <prophetMuhammad/>
  <phrasing>أَنَّ النَّبِيَّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ أَذِنَ</phrasing>
  <shift/> <!-- rendered as ح //-->
</branch>
<branch>
  <theCompiler/>
  <tahamul id="###">وحدثنا</tahamul>
  <anchor id="anchorID"><rawi id=XYZ>مُحَمَّدُ بْنُ عَبْدِ اللَّهِ بْنِ نُمَيْرٍ</rawi></anchor>
  <tahamul id="###">حدثنا</tahamul>
  <rawi id=XYZ>أَبِي</rawi>
  <tahamul id="###">حدثنا</tahamul>
  <rawi id=XYZ>عُبَيْدُ اللَّهِ</rawi>
  <tahamul id="###">قال حدثني</tahamul>
  <rawi id=XYZ>نَافِعٌ</rawi>
  <tahamul id="###">عن</tahamul>
  <rawi id=XYZ>ابْنِ عُمَرَ رَضِيَ اللَّهُ عَنْهُمَا</rawi>
  <tahamul id="###"/>
  <prophetMuhammad/>
  <phrasing>أَنَّ الْعَبَّاسَ رَضِيَ اللَّهُ عَنْهُ اسْتَأْذَنَ النَّبِيَّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ لِيَبِيتَ بِمَكَّةَ لَيَالِيَ مِنًى مِنْ أَجْلِ سِقَايَتِهِ فَأَذِنَ لَهُ</phrasing>
</branch>
تَابَعَهُ
<branch continuedAtAnchor="anchorID">
  <theCompiler/>
  <tahamul id="###"/>
  <rawi id=XYZ>أَبُو أُسَامَةَ</rawi>
  <tahamul id="###"/>
  <!-- ..etc. ommited by compiler //-->
</branch>
<branch continuedAtAnchor="anchorID">
  <theCompiler/>
  <!-- some portion is ommited here //-->
  <tahamul id="###"/>
  <rawi id=XYZ>أَبُو أُسَامَةَ</rawi>
  <tahamul id="###"/>
  <!-- continue same as achorID //-->
</branch>
<branch continuedAtAnchor="anchorID">
  <theCompiler/>
  <!-- some portion is ommited here //-->
  <tahamul id="###"/>
  <rawi id=XYZ>وَعُقْبَةُ بْنُ خَالِدٍ</rawi>
  <tahamul id="###"/>
  <!-- continue same as achorID //-->
</branch>
<branch continuedAtAnchor="anchorID">
  <theCompiler/>
  <!-- some portion is ommited here //-->
  <tahamul id="###"/>
  <rawi id=XYZ>وَأَبُو ضَمْرَةَ</rawi>
  <tahamul id="###"/>
  <!-- continue same as achorID //-->
</branch>
 
</sanad>
حَدَّثَنَا مُسَدَّدٌ قَالَ حَدَّثَنَا إِسْمَاعِيلُ بْنُ إِبْرَاهِيمَ أَخْبَرَنَا أَبُو حَيَّانَ التَّيْمِيُّ عَنْ أَبِي زُرْعَةَ عَنْ أَبِي هُرَيْرَةَ قَالَ
كَانَ النَّبِيُّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ بَارِزًا يَوْمًا لِلنَّاسِ فَأَتَاهُ جِبْرِيلُ فَقَالَ مَا الْإِيمَانُ قَالَ الْإِيمَانُ أَنْ تُؤْمِنَ بِاللَّهِ وَمَلَائِكَتِهِ وَكُتُبِهِ وَبِلِقَائِهِ وَرُسُلِهِ وَتُؤْمِنَ بِالْبَعْثِ قَالَ مَا الْإِسْلَامُ قَالَ الْإِسْلَامُ أَنْ تَعْبُدَ اللَّهَ وَلَا تُشْرِكَ بِهِ شَيْئًا وَتُقِيمَ الصَّلَاةَ وَتُؤَدِّيَ الزَّكَاةَ الْمَفْرُوضَةَ وَتَصُومَ رَمَضَانَ قَالَ مَا الْإِحْسَانُ قَالَ أَنْ تَعْبُدَ اللَّهَ كَأَنَّكَ تَرَاهُ فَإِنْ لَمْ تَكُنْ تَرَاهُ فَإِنَّهُ يَرَاكَ قَالَ مَتَى السَّاعَةُ قَالَ مَا الْمَسْئُولُ عَنْهَا بِأَعْلَمَ مِنْ السَّائِلِ وَسَأُخْبِرُكَ عَنْ أَشْرَاطِهَا إِذَا وَلَدَتْ الْأَمَةُ رَبَّهَا وَإِذَا تَطَاوَلَ رُعَاةُ الْإِبِلِ الْبُهْمُ فِي الْبُنْيَانِ فِي خَمْسٍ لَا يَعْلَمُهُنَّ إِلَّا اللَّهُ ثُمَّ تَلَا النَّبِيُّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ
{ إِنَّ اللَّهَ عِنْدَهُ عِلْمُ السَّاعَةِ }
الْآيَةَ ثُمَّ أَدْبَرَ فَقَالَ رُدُّوهُ فَلَمْ يَرَوْا شَيْئًا فَقَالَ هَذَا جِبْرِيلُ جَاءَ يُعَلِّمُ النَّاسَ دِينَهُمْ
قَالَ أَبُو عَبْد اللَّهِ جَعَلَ ذَلِك كُلَّهُ مِنْ الْإِيمَانِ

من صحيح مسلم

حَدَّثَنَا يَحْيَى بْنُ يَحْيَى التَّمِيمِيُّ أَخْبَرَنَا أَبُو الْأَحْوَصِ ح و حَدَّثَنَا أَبُو بَكْرِ بْنُ أَبِي شَيْبَةَ حَدَّثَنَا أَبُو الْأَحْوَصِ عَنْ أَبِي إِسْحَقَ عَنْ مُوسَى بْنِ طَلْحَةَ عَنْ أَبِي أَيُّوبَ قَالَ جَاءَ رَجُلٌ إِلَى النَّبِيِّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ فَقَالَ دُلَّنِي عَلَى عَمَلٍ أَعْمَلُهُ يُدْنِينِي مِنْ الْجَنَّةِ وَيُبَاعِدُنِي مِنْ النَّارِ قَالَ تَعْبُدُ اللَّهَ لَا تُشْرِكُ بِهِ شَيْئًا وَتُقِيمُ الصَّلَاةَ وَتُؤْتِي الزَّكَاةَ وَتَصِلُ ذَا رَحِمِكَ فَلَمَّا أَدْبَرَ قَالَ رَسُولُ اللَّهِ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ إِنْ تَمَسَّكَ بِمَا أُمِرَ بِهِ دَخَلَ الْجَنَّةَ وَفِي رِوَايَةِ ابْنِ أَبِي شَيْبَةَ إِنْ تَمَسَّكَ بِهِ

في هذا المثال البسيط لاحظ وضع ح لتمثيل سلسلتي سند تتصلان عند أَبُو الْأَحْوَصِ

أي أن الرواية التي وصلت إلى الإمام مسلم كانت

مثال آخر من صحيح مسلم

حَدَّثَنِي أَبُو خَيْثَمَةَ زُهَيْرُ بْنُ حَرْبٍ حَدَّثَنَا وَكِيعٌ عَنْ كَهْمَسٍ عَنْ عَبْدِ اللَّهِ بْنِ بُرَيْدَةَ عَنْ يَحْيَى بْنِ يَعْمَرَ ح و حَدَّثَنَا عُبَيْدُ اللَّهِ بْنُ مُعَاذٍ الْعَنْبَرِيُّ وَهَذَا حَدِيثُهُ حَدَّثَنَا أَبِي حَدَّثَنَا كَهْمَسٌ عَنْ ابْنِ بُرَيْدَةَ عَنْ يَحْيَى بْنِ يَعْمَرَ قَالَ كَانَ أَوَّلَ مَنْ قَالَ فِي الْقَدَرِ بِالْبَصْرَةِ مَعْبَدٌ الْجُهَنِيُّ فَانْطَلَقْتُ أَنَا وَحُمَيْدُ بْنُ عَبْدِ الرَّحْمَنِ الْحِمْيَرِيُّ حَاجَّيْنِ أَوْ مُعْتَمِرَيْنِ فَقُلْنَا لَوْ لَقِينَا أَحَدًا مِنْ أَصْحَابِ رَسُولِ اللَّهِ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ فَسَأَلْنَاهُ عَمَّا يَقُولُ هَؤُلَاءِ فِي الْقَدَرِ فَوُفِّقَ لَنَا عَبْدُ اللَّهِ بْنُ عُمَرَ بْنِ الْخَطَّابِ دَاخِلًا الْمَسْجِدَ فَاكْتَنَفْتُهُ أَنَا وَصَاحِبِي أَحَدُنَا عَنْ يَمِينِهِ وَالْآخَرُ عَنْ شِمَالِهِ فَظَنَنْتُ أَنَّ صَاحِبِي سَيَكِلُ الْكَلَامَ إِلَيَّ فَقُلْتُ أَبَا عَبْدِ الرَّحْمَنِ إِنَّهُ قَدْ ظَهَرَ قِبَلَنَا نَاسٌ يَقْرَءُونَ الْقُرْآنَ وَيَتَقَفَّرُونَ الْعِلْمَ وَذَكَرَ مِنْ شَأْنِهِمْ وَأَنَّهُمْ يَزْعُمُونَ أَنْ لَا قَدَرَ وَأَنَّ الْأَمْرَ أُنُفٌ قَالَ فَإِذَا لَقِيتَ أُولَئِكَ فَأَخْبِرْهُمْ أَنِّي بَرِيءٌ مِنْهُمْ وَأَنَّهُمْ بُرَآءُ مِنِّي وَالَّذِي يَحْلِفُ بِهِ عَبْدُ اللَّهِ بْنُ عُمَرَ لَوْ أَنَّ لِأَحَدِهِمْ مِثْلَ أُحُدٍ ذَهَبًا فَأَنْفَقَهُ مَا قَبِلَ اللَّهُ مِنْهُ حَتَّى يُؤْمِنَ بِالْقَدَرِ
ثُمَّ قَالَ حَدَّثَنِي أَبِي عُمَرُ بْنُ الْخَطَّابِ قَالَ بَيْنَمَا نَحْنُ عِنْدَ رَسُولِ اللَّهِ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ ذَاتَ يَوْمٍ إِذْ طَلَعَ عَلَيْنَا رَجُلٌ شَدِيدُ بَيَاضِ الثِّيَابِ شَدِيدُ سَوَادِ الشَّعَرِ لَا يُرَى عَلَيْهِ أَثَرُ السَّفَرِ وَلَا يَعْرِفُهُ مِنَّا أَحَدٌ حَتَّى جَلَسَ إِلَى النَّبِيِّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ فَأَسْنَدَ رُكْبَتَيْهِ إِلَى رُكْبَتَيْهِ وَوَضَعَ كَفَّيْهِ عَلَى فَخِذَيْهِ وَقَالَ يَا مُحَمَّدُ أَخْبِرْنِي عَنْ الْإِسْلَامِ فَقَالَ رَسُولُ اللَّهِ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ الْإِسْلَامُ أَنْ تَشْهَدَ أَنْ لَا إِلَهَ إِلَّا اللَّهُ وَأَنَّ مُحَمَّدًا رَسُولُ اللَّهِ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ وَتُقِيمَ الصَّلَاةَ وَتُؤْتِيَ الزَّكَاةَ وَتَصُومَ رَمَضَانَ وَتَحُجَّ الْبَيْتَ إِنْ اسْتَطَعْتَ إِلَيْهِ سَبِيلًا قَالَ صَدَقْتَ قَالَ فَعَجِبْنَا لَهُ يَسْأَلُهُ وَيُصَدِّقُهُ قَالَ فَأَخْبِرْنِي عَنْ الْإِيمَانِ قَالَ أَنْ تُؤْمِنَ بِاللَّهِ وَمَلَائِكَتِهِ وَكُتُبِهِ وَرُسُلِهِ وَالْيَوْمِ الْآخِرِ وَتُؤْمِنَ بِالْقَدَرِ خَيْرِهِ وَشَرِّهِ قَالَ صَدَقْتَ قَالَ فَأَخْبِرْنِي عَنْ الْإِحْسَانِ قَالَ أَنْ تَعْبُدَ اللَّهَ كَأَنَّكَ تَرَاهُ فَإِنْ لَمْ تَكُنْ تَرَاهُ فَإِنَّهُ يَرَاكَ قَالَ فَأَخْبِرْنِي عَنْ السَّاعَةِ قَالَ مَا الْمَسْئُولُ عَنْهَا بِأَعْلَمَ مِنْ السَّائِلِ قَالَ فَأَخْبِرْنِي عَنْ أَمَارَتِهَا قَالَ أَنْ تَلِدَ الْأَمَةُ رَبَّتَهَا وَأَنْ تَرَى الْحُفَاةَ الْعُرَاةَ الْعَالَةَ رِعَاءَ الشَّاءِ يَتَطَاوَلُونَ فِي الْبُنْيَانِ قَالَ ثُمَّ انْطَلَقَ فَلَبِثْتُ مَلِيًّا ثُمَّ قَالَ لِي يَا عُمَرُ أَتَدْرِي مَنْ السَّائِلُ قُلْتُ اللَّهُ وَرَسُولُهُ أَعْلَمُ قَالَ فَإِنَّهُ جِبْرِيلُ أَتَاكُمْ يُعَلِّمُكُمْ دِينَكُمْ
حَدَّثَنِي مُحَمَّدُ بْنُ عُبَيْدٍ الْغُبَرِيُّ وَأَبُو كَامِلٍ الْجَحْدَرِيُّ وَأَحْمَدُ بْنُ عَبْدَةَ قَالُوا حَدَّثَنَا حَمَّادُ بْنُ زَيْدٍ عَنْ مَطَرٍ الْوَرَّاقِ عَنْ عَبْدِ اللَّهِ بْنِ بُرَيْدَةَ عَنْ يَحْيَى بْنِ يَعْمَرَ قَالَ لَمَّا تَكَلَّمَ مَعْبَدٌ بِمَا تَكَلَّمَ بِهِ فِي شَأْنِ الْقَدَرِ أَنْكَرْنَا ذَلِكَ قَالَ فَحَجَجْتُ أَنَا وَحُمَيْدُ بْنُ عَبْدِ الرَّحْمَنِ الْحِمْيَرِيُّ حَجَّةً وَسَاقُوا الْحَدِيثَ بِمَعْنَى حَدِيثِ كَهْمَسٍ وَإِسْنَادِهِ وَفِيهِ بَعْضُ زِيَادَةٍ وَنُقْصَانُ أَحْرُفٍ و حَدَّثَنِي مُحَمَّدُ بْنُ حَاتِمٍ حَدَّثَنَا يَحْيَى بْنُ سَعِيدٍ الْقَطَّانُ حَدَّثَنَا عُثْمَانُ بْنُ غِيَاثٍ حَدَّثَنَا عَبْدُ اللَّهِ بْنُ بُرَيْدَةَ عَنْ يَحْيَى بْنِ يَعْمَرَ وَحُمَيْدِ بْنِ عَبْدِ الرَّحْمَنِ قَالَا لَقِينَا عَبْدَ اللَّهِ بْنَ عُمَرَ فَذَكَرْنَا الْقَدَرَ وَمَا يَقُولُونَ فِيهِ فَاقْتَصَّ الْحَدِيثَ كَنَحْوِ حَدِيثِهِمْ عَنْ عُمَرَ رَضِيَ اللَّهُ عَنْهُ عَنْ النَّبِيِّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ وَفِيهِ شَيْءٌ مِنْ زِيَادَةٍ وَقَدْ نَقَصَ مِنْهُ شَيْئًا و حَدَّثَنِي حَجَّاجُ بْنُ الشَّاعِرِ حَدَّثَنَا يُونُسُ بْنُ مُحَمَّدٍ حَدَّثَنَا الْمُعْتَمِرُ عَنْ أَبِيهِ عَنْ يَحْيَى بْنِ يَعْمَرَ عَنْ ابْنِ عُمَرَ عَنْ عُمَرَ عَنْ النَّبِيِّ صَلَّى اللَّهُ عَلَيْهِ وَسَلَّمَ بِنَحْوِ حَدِيثِهِمْ

جاء في مقدمة ابن الصلاح

حديث:من كذب علي متعمدا فليتبوأ مقعده من النار “ نراه مثالا لذلك، فإنه نقله من الصحابة رضى الله عنهم العدد الجم، وهو في الصحيحين مروي عن جماعة منهم ذكر أبو بكر البزار الحافظ الجليل في مسنده: أنه رواه عن رسول الله صلى الله عليه وسلم نحو من أربعين رجلا من الصحابة. وذكر بعض الحفاظ أنه رواه عنه صلى الله عليه وسلم اثنان وستون نفساً من الصحابة، وفيهم العشرة المشهود لهم بالجنة.

وهذا لأنه متواتر لذا يصل لكل هذا لكن هذه الطرق لا تجتمع في كتاب واحد أو في مكان واحد من الكتاب.

وعزو الحديث أو الأثر إلى من ذكره تدوينا بالإسناد يسمى تخريجا (أي العزو إلى المصادر الأصلي التي تروي الأحاديث بالإسناد)، فيصح أن يقال أخرجه البخاري، لأنه يذكر الحديث بالإسناد، لكن لا يصح أن يقال أخرجه الألباني في كتاب كذا وكذا لأنه لا يرويه بإسناده (أي إسناد الألباني) إلى النبي صلى الله عليه وسلم أو من روي عنه الأثر.

وقد ذكر السيوطي أسماء الصحابة الذي رووا هذا الحديث، قال رحمه الله (والخاص بهذا المتن رواية بضعة وسبعين صحابيا العشرة المشهود لهم بالجنة أسامة قا أنس بن مالك خ م أوس بن أوس طب البراء بن عازب طب بريدة عد جابر بن حابس مع جابر بن عبد الله م حذيفة بن أسد طب حذيفة بن اليمان طب خالد بن عرطفة حم رافع بن خديج طب زيد بن ارقم حم زيد بن ثابت خل السائب بن يزيد طب سعد بن المدحاس خل سفينة عد سليمان بن خالد الخزاعي قط سلمان الفارسي قط سلمة بن الأكوع خ صهيب بن سنان طب عبد الله بن أبي أوفى قا عبد الله بن زغب بع ابن الزبير قط ابن عباس طب ابن عمر حم بن عمرو خ ابن مسعود ت ن عتبة بن غزوان طب العرس بن عميرة طب عفان بن حبيب ك عقبة بن عامر حم عمار بن ياسر طب عمران بن حصين بن عمرو بن حريث طب عمرو بن عبسة طب عمرو بن عوف طب عمرو بن مزة الجهني طب قيس بن سعد بن عبادة حم كعب ابن قطبة خل معاذ بن جبل طب معاوية بن حيدة خل معاوية بن أبي سفيان حم المغيرة بن شعبة نع المنفع التيمي خل نبيط بن شريط طب واثلة بن الأسقع عد يزيد بن أسد قط يعلى بن مرة مي أبو أسامة طب أبو الحمراء طب أبو ذر قط أبو رمثة قط ابو سعيد الخدري حم أبو قتادة أبو قرصافة عد أبو كبشة الأنماري خل أبو موسى الأشعري طب أبو موسى الغافقي حم أبو ميمون الكردي طب أبو هريرة والدأبي العشراء الدارمي خل والدأبي مالك الأشجعي بز عائشة قط أم أيمن قط)

ورموز التخريج هذه يعرفها أصحاب الصنعة وهي أسماء الكتب

حم في مسنده لأحمد وطب للطبراني وقط للدارقطني وعد لابن عدي في الكامل وبز لمسند البزار وقا لابن قانع في معجمه وخل للحافظ يوسف بن خليل في كتابه الذي جمع فيه طرق هذا الحديث ونع لأبي نعيم ومي لمسند الدارمي وك لمستدرك الحاكم وت للترمذي ون للنسائي وخ م للبخاري ومسلم)

مع ملاحظة ما يلي:

اختبار نموذج البيانات

نظريا

نأخذ أي من كتب الحديث مثل صحيح البخاري ثم نفترض أن نصف حجم الكتاب سند ونصفه متن ونفترض أن المتن كلام غير مرقوم ونجمع أطوال أسماء الرواة في 3 صفحات من الأول ومثلها من الوسط ومثلها من آخر الكتاب ونكرر ذلك مع الصلة بين الرواة ثم نحسب النسبة بين هذه وتلك كأن نقول أن 60% من النص كان للرواة و40% كان للصلة بينهما ونحسب متوسط عدد الرواة.

ومن معرفة كل ذلك نستطيع توقع طريقة توزيع هرمية الكتاب على صفوف قاعدة البيانات ومنها نستطيع تقييم النموذج عبر بيانات وهمية مكررة للمتوسط.

يتبع لاحقا جمع تلك البيانات ومقارنتها في كل نموذج. واختبار حجم وعبئ وسرعة كل نموذج

عمليا

اختيار مجموعة من الكتب واستيرادها للنوذج المختار وتقييم النموذج

التنفيذ

نوذج البيانات Data model الخام

ثلاث جدول واحد nodesTable يمثل شجرة العقد ويحتوي

nodeID parentNodeID siblingOrder contents

وآخر يحتوي قائمة بكل الراقمات tagsTable المخصصة

tagID tagType tagName comment

وثالث nodeTags يربط كل عقدة بعدد من الراقمات

nodeID tageID param

وقد لا نحتاج لحقل param

عملية استخراج الشجرة المرقومة بالكامل تتم بعملية left join

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID;

استخراج جدول المحتويات (غير مرتب حتى هذه الخطوة) يكون

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID WHERE nodeTags.tagID=0;

حيث أن القيمة صفر لمعرف الراقمة تعني أنها تعرف مدخلة في جدول المحتويات.

يمكن استخراج جذر كل عقد السند

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID LEFT OUTER JOIN tagsTable on nodeTags.tagId=tagsTable.tagId WHERE tagsTable.tagName="Sanad";

القيام بالمزيد من العمليات يحتاج إلى استخدام حقل nodePath

محددات التحسين optimization

يمكن تحديد سلوك الراقمة عبر tagType عبر bit field

سلوك الراقمة عند العرض
2 بت معناها
0 0 راقمة تعرف عنصر غير مرئي كتعريف نقطة مرساة
1 0 الراقمة تعرف لبنة منفصلة block وقد تكون طافية
0 1 الراقمة تعرف عنصر سطري inline مندمج دون مسافات
1 1 الراقمة تعرف عنصر سطري inline معزول كأن يكون محاطا بمسافات
مصدر بياناتها
2 بت معناها
0 0 قيمة نصية
1 0 قيمة عددية صحيحة
0 1 جدول الوسائط داخل نفس قاعدة البيانات
1 1 ملف عبر URL كأن يكون ملف محلي أو عبر الشبكة

حفظ مسار العقدة

يمكن إدراج حقل nodePath على شكل سلسلة نصية. ولتحسين سبل الوصول نقسهما إلى 20 حقل L1 L2 … L20 ونعمل فهرسة عليها وهذا يجعلها محدودة حتى العمق 20. وبهذه الطريقة إن كنا نريد أن نستخرج سلسلة السند كلها المتعلقة بحديث ما نحتاج وكان جذر هذه السلسلة عند العقدة الفلانية نأخذ قيمة L1 L2 حتى آخر واحدة ليست null ونستعلم عنها

استخراج جدول المحتويات مرتب بطريقة depth first يكون

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID WHERE nodeTags.tagID=0 ORDER by L1,L2,L3...;

ولا يوجد طريقة مباشر للترتيب بطريقة breadth-first لكن هذا كما قلنا غير ضروري.

محدودية العمق حتى 20 يجعلنا نضطر لتمثيل شجرة الرواة على شكل مجموعة من السلاسل كل راوي فيها يكون في عقدة شقيقة على نفس العمق لمن روى عنه وعنه وعنه …إلخ وليس شجرة وهو تمثيل مكافئ لكنه يزيد التعقيد على البرنامج ال front end في إعادة تكوين الشجرة.

عدم حفظ مسار العقدة مستعينا بالترتيب الشامل

في هذا النموذج نلغي nodePath بالمطلق ونضيف حقل جديد باسم level ليمثل عمق المسار ونجعل الحقل siblingOrder عبارة عن nodeOrder أي ترتيب العقدة الكامل بطريقة depth first وأفضل الخيارات أن يكون حقلا من نوع Float حيث نستطيع حشر المزيد من العقد عبر الوسط الحسابي دون الحاجة للمرور عليها مجددا. وفي هذا النموذج لا يكون أمامنا أي حد للعمق لذا نمثل الروى على شكل شجرة فعليا.

هذا النموذج يحقق لنا محددات التصميم لكن لا يمكننا أن نعرف فيه مسار العقدة لصف ما باستعلام واحد لكن أوجه استخدام البرنامج لا تتطلب معرفة المسار إلا ضمن الوحدة الجوهرية التي تكون محملة كلها في الذاكرة بعد الحصول على نتيجة استعلام ما وهذا أمر يسير.

سرد العقد صفا صفا بترتيب العمق أولا depth first يكون عبر

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID WHERE nodeTags.tagID=0 ORDER BY nodesTable.nodeOrder

أما طريقة breadth-first فتكون عبر

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID WHERE nodeTags.tagID=0 ORDER BY nodesTable.level,nodesTable.nodeOrder

وبهذه الطريقة إن كنا نريد أن نستخرج شجرة السند كلها المتعلقة بحديث ما (وهنا لا نحدد الحديث بمسارع بل نبحث عن قيم X و Y التي يقع سند الحديث فيها)

SELECT * FROM nodesTable LEFT OUTER JOIN nodeTags ON nodesTable.nodeID = nodeTags.nodeID WHERE nodesTable.nodeOrder>X AND nodesTable.nodeOrder<Y ORDER BY nodesTable.nodeOrder

نقاط لم يعد لها مكان

هذه نقاط ستم حذفها

نموذج البيانات data model

الشاملة 3 وبالتالي ثواب 2 تستعمل عدة جداول منفصلة وما يزيد الامر سوءا أن الشاملة لم تلزم بعض الحقول بأن تكون فريدة.

سيكون هناك نماذج كل صف فيها هو وحدة جوهرية والبيانات داخلها تكون مرقومة بواسطة xml أو ما يؤدي الغرض منها

الطريقة الاخرى أن نستخدم الجدول في رقم النص بالكامل حيث لا تكون الوحدة الجوهرية في صف مستقل بل تكون كل راقمة tag للنص في صف ولا تحتوي صفوف الجدول أي راقمات.

أول المحاولات

أول ما خطر ببالي إلزام معرف لكل صف في الجدول بأن يكون فريدا وأن تنقل بعض المعلومات منه إلى جدول toc ولأنه فريد فإن عملية الربط joining ستكون سريعة

'book':"id INTEGER PRIMARY KEY, xml TEXT",
'toc': "id INTEGER PRIMARY KEY, title TEXT, level INTEGER"

عند التصدير لأي هيئة يتم زراعة كود xml بالطريقة التالية

<book>
 <section id="$id" title="$title">
 $xml
 </section>
 <section id="$id" title="$title">
 $xml
      <section id="$id" title="$title">
      $xml
     </section>
      ...
 </section>
...
</book>

ويتم الاختيار بين زرع كود xml داخل الفصل السابق أم تاليا له تبعا لقيمة level فإن كانت نفس القيمة كانت تليها وإن كانت أكبر منها بواحد كانت داخلها

النوذج الأول لفكرة الجدول الواحد

اقترح علي أخي المهندس كفاح أن يتم توحيد كل البيانات ما أمكن في جدول واحد حيث أن عملية الفهرسة للجدول تجعل زمن الوصول للبيانات ثابت ‎ O(1) ‎إذا تم بطلب واحد 1) لكن الطرق الاخرى تحتاج عمليات join وعمل أكثر من query

لذا قمت بعمل محددات التصميم أعلاه التي يجب أن تؤخذ بعين الاعتبار عند وضع النموذج

وهذا مثال على النموذج

معرف الصف nodeId المسار nodePath مستوى العمق level معرف الصف للوالد parentId العنوان title البيانات data
0 0 0 0 عنوان الكتاب الصف الأول خاص فهو جد للصفوف وهو يحتوي بيانات metadata الخاصة بالكتاب
1 0-1 1 0 باب الألوان الحارة محتوايته
2 0-2 1 0 باب الألوان الباردة محتوايته
3 0-1-3 2 1 فصل الأحمر محتوايته
4 0-1-4 2 1 فصل الأصفر محتوايته
5 0-2-5 2 1 فصل الأزرق محتوايته
6 0-2-6 2 1 فصل البنفسجي محتوايته

من السهل ملاحظة كيف أن هذا النموذج يحقق لنا محددات التصميم

لتسريع عملية الوصول وتوفير الوقت لا نقوم بحفظ المسار nodePath على شكل نص بل على شكل عدة حقول l1 l2 l3 … l20 وهذا الرقم أكثر من كافي.

إن كنا نكتب كتابا بحتاج وضع علامة ما مثلا رقم الصفحة الورقية أو ربط صفحة بمعرف شرحها في كتاب آخر أو إن كانت الصفحة تفسيرا لآية …إلخ. كل هذا يمكن أن يكون عبر نص مرقوم داخل البيانات لكن إن كان البحث عنها مفيدا يمكن تخصيص حقل لها كأن يكون هناك حقل باسم nodeType يحدد هل الصف الحالي صف محتويات أم أنه يحتوي علامة …إلخ.

فإذا أردنا كل ما في “باب الألوان الباردة” نطلب l1=2 وإن كنا نريد كل ما تحت “فصل البنفسجي” نطلب l1=2 and l2=6

عمليات التعديل مثل إضافة “فصل البرتقالي” تجعل الصفوف غير منتظمة ولحل هذا يمكن استخدام واحد من بين:

  1. يمكن إضافة حقل مفهرس جديد اسمه sortOrder من نوع FLOAT يوضع فيه الوسط الحسابي لقيمتيه في الصفين اللذان سيحشر بينهما. هذا التريب هو التريب وفق depth first. وحيث أنه حقل مفهرس لن يكون هناك ترتيب.
  2. إضافة حقل مفهرس من نوع integer يحدد الترتيب داخل العمق الوحد فقط (عملية الحشر تحتاج ترتيب العناصر في ذاك العمق فقط)
  3. أن يكون الرقم المكتوب في آخر المسار lN حيث N هي level ليس رقم الصف بل ترتيب الصف بين أشقائه.

النوذج الثاني المختزل

في هذا النموذج نعتمد على الترتيب عبر sortOrder وليس nodePath

nodeId sortOrder level parentId title data
0 1.0 0 0 عنوان الكتاب الصف الأول خاص فهو جد للصفوف وهو يحتوي بيانات metadata الخاصة بالكتاب
1 2.0 1 0 باب الألوان الحارة محتوايته
2 5.0 1 0 باب الألوان الباردة محتوايته
3 3.0 2 1 فصل الأحمر محتوايته
4 4.0 2 1 فصل الأصفر محتوايته
5 6.0 2 1 فصل الأزرق محتوايته
6 7.0 2 1 فصل البنفسجي محتوايته

هذا النموذج يحقق لنا محددات التصميم لكن لا يمكننا أن نعرف فيه مسار العقدة لصف ما باستعلام واحد لكن أوجه استخدام البرنامج لا تتطلب معرفة المسار.

سرد العقد صفا صفا بترتيب العمق أولا depth first يكون عبر

ORDER BY sortOrder

أما طريقة breadth-first فتكون عبر

ORDER BY level,sortOrder

نموذج صفوفه الراقمات tags دون أي رقم النص الداخلي

nodeId sortOrder level parentId nodeType strValue intValue

وهذا النموذج مثل الذي قبله لكن فيه لا تكون الوحدة الجوهرية (مثلا الحديث الواحد) في صف مستقل بل تكون كل راقمة tag هي التي في صف مستقل فلا نحتاج لوضع أو استعمال binary serialization for xml أي أننا سنستخدم sqlite كبديل عنها. أما قيم nodeType فهي

  1. العقدة الحالية هي الجد للوحدة الجوهرية وهي يجب أن تظهر في جدول المحتويات (في مثالنا ذاك يعني أن الحديث هو فروع هذه العقدة) وتكون StrValue هي العنوان الذي يظهر في جدول المحتويات
  2. بيانات العقدة الحالية تعرف خاصية id لوالدها parent وذاك كي تستخدم في عمل إحالة له
  3. بيانات العقدة الحالية معرف الآيات في كتب التفسير (السورة - الآية - عدد الآيات عبر عمل bit field وتوضع في intValue من أجل الفهرسة والترتيب)
  4. بيانات العقدة الحالية رقم الصفحة في النسخة المطبوعة (يمكن استعمال أكثر من واحدة حيث يوضع في strValue معرف نصي للطبعة التي أخذ رقم الصفحة منها مثلا الطبعة الثانية من دار كذا - طبعا نكتفي بمعرف ويربط بالنص الكامل في مكان آخر)
  5. دمج وسيط داخلي (صورة أو صوت …)
  6. دمج وسيط خارجي
  7. إحالة ulink
  8. علاقة شرح ل (معرف uri للكتاب المشروح ورقم معرف الإحالة)
  9. فقرة جديدة (هل نحتاج لها حيث لنا استخدام “سطر فارغ” داخل النص)
  10. اقتباس على السطر
  11. اقتباس في لبنة
  12. كود على السطر
  13. كود في لبنة
  14. نص غير مرقوم يرث راقمة والده
  15. حاشية أو تعليق (للمحقق مثلا) الرقم هنا هو معرف مجموعة الحواشي ويشير لصاحب الحاشية إن كان هناك أكثر من حاشية
  16. متن الحديث
  17. سند الحديث
  18. سلسلة رواية
  19. راو في سلسلة الرواية (الرقم هو المعرف والنص هو الاسم حرفيا كما في الكتاب)
  20. رابط بين راويين (حدثني أو أخبرني … مع معرفها والمعرف 0 يعني أخرى)

انواع الراقمات tags المسموحة

الراقمات يجب أن توضح وظيفة النص الذي ترقمه لا مظهره مثلا لا نقول هذا ثغين وهذا مائل … بل نقول هذا مصطلح وهذا تعريفه …إلخ.

الراقمات المعرفة يجب أن ترث أحد الصفات التالية.


مثلا “السند” و “المتن” راقمات سطرية في الحديث الذي هو لبنة.

البرامج التي تعرض النص المرقوم تحاول تمثيل الجزء المرقوم عبر في شجرة هرمية لسمات الراقمات مثلا إن لم يكن هناك مظهل معرف للسند فإنه سيظهر كنص عادي داخل الفقرة.

أما الفائدة الكبرى من الراقمات فهي من أجل البحث إذ يفترض في محرك البحث أن يفهم النص المرقوم ويسهل البحث فيه كأن تبحث في السند دون المتن.

كذلك يفيد في عمل خلاصات وترقيم تلقائي للنص المرقوم كأن يتم توليد جدول بكل الأمثلة المحلولة في الباب من كتاب فيزياء مثلا.

مشاريع للنظر فيها

دراسة طرق بديلة ل xml ما يهما بشكل أساسي هو عملية Serialization لعدة أسباب منها

ملاحظات على كل منها

كتب للاطلاع

ومن الاخيرة أقتبس

فأولها: صحيح أخرجه البخاري ومسلم جميعأ.
الثاني: صحيح انفرد به البخاري، أي عن مسلم.
الثالث: صحيح انفرد به مسلم، أي عن البخاري.
الرابع: صحيح على شرطهما، لم يخرجاه.
الخامس: صحيح على شرط البخاري، لم يخرجه.
السادس: صحيح على شرط مسلم، لم يخرجه.
السابع: صحيح عند غيرها، وليس على شرط واحد منها.