Problemas de reindex de Algolia

Al realizar algolia:reindex usando la tarea de rake, se bloqueó con el siguiente error

Clearing users from Algolia
Pushing users to Algolia
...
Successfully pushed 1849 users to Algolia
Clearing tags from Algolia
Pushing tags to Algolia
..
Successfully pushed 53 tags to Algolia
Clearing posts from Algolia
Pushing posts to Algolia
rake aborted!
Algolia::AlgoliaHttpError: Record at the position 662 objectID=690 is too big size=20920/20000 bytes. Please have a look at 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)

Hasta donde puedo ver, el plugin no contiene ninguna funcionalidad para dividir publicaciones más largas en fragmentos separados. Pude solucionar el problema al no incluir publicaciones largas agregando

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

justo antes de la llamada a @index.save_objects, pero también significa que estas publicaciones no se indexan en absoluto.

2 Me gusta

¿Alguna idea de lo que espera la API? ¿Debemos truncarlo o enviarlo en varios fragmentos?

Según Index long pages - Algolia debe dividirse en fragmentos y distinct debe establecerse en true al buscar.

El tamaño máximo depende del plan (depende del plan), pero no encuentro una forma de consultarlo. Dado que también existe un límite de “tamaño promedio de registro en todos los registros” en ciertos planes, podría ser bueno dividir en fragmentos de 10 KB 10000 bytes.

2 Me gusta

Solución al error “Record is too big” que aborta el reindexado de publicaciones en Algolia

Me encontré con un problema en el que Algolia solo contenía una pequeña parte de las publicaciones de mi foro. Al ejecutar el reindexado de publicaciones, se reveló la causa:

Algolia::AlgoliaHttpError:
Record at the position 258 objectID=1006 is too big:
size: 108426 byte(s), maximum allowed: 10000 byte(s).

En la versión del plugin que tengo instalada, PostIndexer#to_object envía todo el texto plano de la publicación como un único registro sin comprobar el tamaño de este una vez serializado. Un registro de tamaño excesivo provocaba que la tarea de reindexado se abortara.

La siguiente solución temporal local permitió que el reindexado se completara.

Qué hace este parche

El parche limita cada registro de publicación serializado completo a 9.500 bytes, dejando un margen por debajo del límite de 10.000 bytes reportado por Algolia.

Esto:

  • Incluye los metadatos y el escapado JSON en el cálculo del tamaño.

  • Trunca solo el content enviado a Algolia.

  • Deja la publicación original de Discourse intacta.

  • Mantiene los IDs de objeto existentes y la estructura de un registro por publicación.

El compromiso es que el texto omitido al final de una publicación larga no será buscable a través de Algolia. Esto es truncamiento, no fragmentación del documento.

Parche

En:

plugins/discourse-algolia/lib/discourse_algolia/post_indexer.rb

Busca el return final en to_object, inmediatamente después de que se añadan los metadatos de categoría opcionales:

    object
  end

Reemplaza esa sección con:

# Limitar el registro serializado completo, no solo su contenido.
    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

La búsqueda binaria encuentra un prefijo del contenido que se ajusta al límite de bytes tras la serialización JSON. Si los metadatos por sí solos superan el límite, el parche lanza un error explícito en lugar de descartar los metadatos silenciosamente.

Haz una copia de seguridad del archivo antes de editarlo. Este parche está destinado a la versión donde to_object devuelve un único hash que contiene content; revísalo contra tu versión instalada antes de aplicarlo.

Validar y reindexar

Para una instalación estándar de Docker, entra en el contenedor desde el host:

cd /var/discourse
./launcher enter app

Cambia al usuario Discourse:

su - discourse

Una vez que aparezca el prompt del usuario discourse, ejecuta:

cd /var/www/discourse
ruby -c plugins/discourse-algolia/lib/discourse_algolia/post_indexer.rb

Si esto reporta Syntax OK, ejecuta:

RAILS_ENV=production LOAD_PLUGINS=1 bundle exec rails algolia:reindex_posts

Esta tarea borra y repuebla el índice de publicaciones. En mi caso, se completó con éxito tras aplicar el parche.

Los procesos de la aplicación/trabajadores en segundo plano ya en ejecución también necesitan reiniciarse para utilizar el código parcheado en el indexado continuo.

Otro detalle a tener en cuenta: el recuento de publicaciones informado

La tarea informó:

Successfully pushed 723 posts to Algolia
But Algolia contained 272 records.

Pero Algolia contenía 272 registros.

En mi versión instalada, la tarea incrementa su contador antes de llamar al filtro de visibilidad del indexador. Un diagnóstico utilizando el mismo indexador confirmó:

Posts examined:         723
Eligible for indexing:  272
Excluded by visibility: 451

Por lo tanto, el mensaje de éxito cuenta las publicaciones examinadas, no necesariamente los registros subidos. Esta discrepancia era independiente del error de registro de tamaño excesivo.