إصلاح لخطأ “Record is too big” الذي يؤدي إلى إلغاء إعادة فهرسة مشاركات Algolia
واجهت مشكلة حيث كانت Algolia تحتوي فقط على جزء صغير من مشاركات منتدي. وكشفت إعادة فهرسة المشاركات عن السبب:
Algolia::AlgoliaHttpError:
Record at the position 258 objectID=1006 is too big:
size: 108426 byte(s), maximum allowed: 10000 byte(s).
في الإصدار المثبت من الإضافات، ترسل PostIndexer#to_object النص العادي للمشاركات بالكامل كسجل واحد دون التحقق من حجم السجل المشفر. وتسبب السجل الذي يتجاوز الحد الأقصى في إلغاء مهمة إعادة الفهرسة.
وسمح الحل البديل المحلي التالي بإكمال إعادة الفهرسة.
ماذا يفعل هذا التصحيح
يحدّ التصحيح من كل سجل مشاركات مكتمل التسلسل إلى 9500 بايت، تاركاً هامشاً تحت حد 10000 بايت المبلغ من قبل Algolia.
فهو:
- يتضمن البيانات الوصفية وتهريب JSON في حساب الحجم.
- يقص فقط
content المرسل إلى Algolia.
- يترك مشاركات Discourse الأصلية دون تغيير.
- يحتفظ بمعرّفات object الموجودة وهيكل سجل واحد لكل مشاركة.
المقايضة هي أن النص المحذوف من نهاية مشاركة طويلة لن يكون قابلاً للبحث عبر Algolia. هذا التقليم ليس تقطيعاً للوثائق.
التصحيح
في:
plugins/discourse-algolia/lib/discourse_algolia/post_indexer.rb
ابحث عن الإرجاع النهائي في to_object، مباشرة بعد إضافة البيانات الوصفية الاختيارية للفئة:
object
end
استبدل هذا القسم بـ:
# Limit the complete serialized record, not just its content.
algolia_record_budget = 9_500
if object.to_json.bytesize > algolia_record_budget
full_content = object[:content]
object[:content] = ""
if object.to_json.bytesize > algolia_record_budget
raise "Algolia metadata alone exceeds the record budget for post #{post.id}"
end
low = 0
high = full_content.length
best_content = ""
while low <= high
midpoint = (low + high) / 2
object[:content] = full_content[0, midpoint]
if object.to_json.bytesize <= algolia_record_budget
best_content = object[:content]
low = midpoint + 1
else
high = midpoint - 1
end
end
object[:content] = best_content
end
object
end
يحدد البحث الثنائي بادئة للمحتوى تتناسب مع ميزانية البايتات بعد تسلسل JSON. وإذا تجاوزت البيانات الوصفية وحدها الميزانية، يرفع التصحيح خطأً صريحاً بدلاً من تجاهل البيانات الوصفية بصمت.
خذ نسخة احتياطية من الملف قبل التعديل. يستهدف هذا التصحيح الإصدار الذي تعيد فيه to_object hash واحداً يحتوي على content؛ راجعه مع الإصدار المثبت لديك قبل التطبيق.
التحقق وإعادة الفهرسة
لتثبيت Docker القياسي، ادخل إلى الحاوية من المضيف:
cd /var/discourse
./launcher enter app
تبديل إلى مستخدم Discourse:
su - discourse
بمجرد ظهور مطالبة المستخدم discourse، قم بتشغيل:
cd /var/www/discourse
ruby -c plugins/discourse-algolia/lib/discourse_algolia/post_indexer.rb
إذا تم الإبلاغ عن Syntax OK، قم بتشغيل:
RAILS_ENV=production LOAD_PLUGINS=1 bundle exec rails algolia:reindex_posts
تقوم هذه المهمة بمسح فهرس المشاركات وإعادة تعبئته. في حالتي، اكتملت بنجاح بعد تطبيق التصحيح.
تحتاج أيضاً عمليات التطبيق/العامل الخلفية قيد التشغيل إلى إعادة تشغيل لاستخدام الكود المصحح للفهرسة الجارية.
مأزق منفصل: عدد المشاركات المبلغ
أبلغت المهمة عن:
Successfully pushed 723 posts to Algolia
But Algolia contained 272 records.
لكن كانت Algolia تحتوي على 272 سجلاً.
في الإصدار المثبت، تزداد عداد المهمة قبل استدعاء مرشح الرؤية الخاص بالمفهرس. وأكد تشخيص باستخدام نفس المفهرس:
Posts examined: 723
Eligible for indexing: 272
Excluded by visibility: 451
لذلك يحسب رسالة النجاح المشاركات المفحوصة، وليس بالضرورة السجلات المرفوعة. كان هذا التناقض منفصلاً عن خطأ السجل ذي الحجم المفرط.