Algolia reindex مشاكل

أثناء تنفيذ algolia:reindex باستخدام مهمة الـ rake، تعطلت مع الخطأ التالي:

مسح المستخدمين من Algolia
دفع المستخدمين إلى Algolia
...
تم دفع 1849 مستخدمًا بنجاح إلى Algolia
مسح العلامات من Algolia
دفع العلامات إلى Algolia
..
تم دفع 53 علامة بنجاح إلى Algolia
مسح المنشورات من Algolia
دفع المنشورات إلى Algolia
تم إلغاء مهمة الـ rake!
Algolia::AlgoliaHttpError: السجل في الموضع 662 objectID=690 كبير جدًا الحجم=20920/20000 بايت. يرجى إلقاء نظرة على https://www.algolia.com/doc/guides/sending-and-managing-data/prepare-your-data/in-depth/index-and-records-size-and-usage-limitations/#record-size-limits (Algolia::AlgoliaHttpError)

على حد علمي، لا يحتوي المكون الإضافي على أي وظيفة لتقسيم المنشورات الأطول إلى أجزاء منفصلة. تمكنت من تجاوز المشكلة عن طريق عدم تضمين المنشورات الطويلة بإضافة

objects.reject! { |object| object.to_json.bytesize > 20000 }

مباشرة قبل استدعاء @index.save_objects ولكن هذا يعني أيضًا أنه لم يتم فهرسة هذه المنشورات على الإطلاق.

إعجابَين (2)

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

وفقًا لـ Index long pages - Algolia ، يجب تقسيمه، ويجب تعيين distinct على true عند البحث.

الحد الأقصى للحجم هو يعتمد على الخطة ولكن لا يمكنني العثور على طريقة للاستعلام عنه. نظرًا لوجود حد “متوسط حجم السجل عبر جميع السجلات” أيضًا في خطط معينة، فقد يكون من الجيد التقسيم عند 10 كيلوبايت 10000 بايت.

إعجابَين (2)

إصلاح لخطأ “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

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