Problemi di reindicizzazione di Algolia

Durante l’esecuzione di algolia:reindex utilizzando il rake task, si è verificato il seguente errore:

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)

Per quanto vedo, il plugin non contiene alcuna funzionalità per suddividere post più lunghi in blocchi separati. Sono riuscito a risolvere il problema non includendo i post lunghi aggiungendo

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

subito prima della chiamata @index.save_objects, ma ciò significa anche che questi post non vengono affatto indicizzati.

2 Mi Piace

Qualche idea su cosa si aspetta l’API? Dovremmo troncarlo o inviarlo in più parti?

Per Index long pages - Algolia deve essere suddiviso in blocchi e distinct deve essere impostato su true durante la ricerca.

La dimensione massima è dipendente dal piano, ma non riesco a trovare un modo per interrogarla. Dato il fatto che esiste anche un limite di “dimensione media dei record su tutti i record” su determinati piani, potrebbe essere opportuno suddividere in blocchi a 10 KB 10000 byte.

2 Mi Piace

Correzione per l’errore “Record is too big” che interrompe la reindicizzazione dei post di Algolia

Ho riscontrato un problema in cui Algolia conteneva solo una piccola parte dei post del mio forum. L’esecuzione della reindicizzazione dei post ha rivelato la causa:

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

Nella versione del plugin installata nel mio ambiente, PostIndexer#to_object invia l’intero testo in chiaro di un post come singolo record, senza verificare la dimensione del record serializzato. Un record eccessivamente grande causava l’interruzione del task di reindicizzazione.

La seguente soluzione alternativa locale ha permesso alla reindicizzazione di completarsi.

Cosa fa questa patch

La patch limita ogni record completo di post serializzato a 9.500 byte, mantenendo un margine al di sotto del limite di 10.000 byte segnalato da Algolia.

Fa sì che:

  • Il calcolo della dimensione includa i metadati e l’escaping JSON.

  • Venga troncato solo il campo content inviato ad Algolia.

  • Il post originale su Discourse rimanga invariato.

  • Vengano conservati gli ID oggetto esistenti e la struttura di un record per ogni post.

Il compromesso è che il testo omesso alla fine di un post lungo non sarà cercabile tramite Algolia. Si tratta di troncamento, non di suddivisione del documento in chunk.

Patch

In:

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

Trova il valore di ritorno finale in to_object, immediatamente dopo l’aggiunta dei metadati facoltativi della categoria:

    object
  end

Sostituisci quella sezione con:

# 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

La ricerca binaria individua un prefisso del contenuto che rientra nel budget di byte dopo la serializzazione JSON. Se i soli metadati superano il budget, la patch solleva un errore esplicito invece di scartare silenziosamente i metadati.

Effettua il backup del file prima della modifica. Questa patch è destinata alla versione in cui to_object restituisce un singolo hash contenente content; esaminala rispetto alla tua versione installata prima di applicarla.

Valida e reindicizza

Per un’installazione Docker standard, accedi al container dall’host:

cd /var/discourse
./launcher enter app

Passa all’utente Discourse:

su - discourse

Una volta che appare il prompt dell’utente discourse, esegui:

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

Se viene riportato Syntax OK, esegui:

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

Questo task cancella e ripopola l’indice dei post. Nel mio caso, dopo l’applicazione della patch si è completato con successo.

Anche i processi applicativi/background worker già in esecuzione devono essere riavviati per utilizzare il codice patchato per l’indicizzazione continua.

Un’altra insidia: il numero di post segnalato

Il task ha riportato:

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

Ma Algolia conteneva 272 record.

Nella mia versione installata, il task incrementa il contatore prima di chiamare il filtro di visibilità dell’indexer. Una diagnostica che utilizzava lo stesso indexer ha confermato:

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

Pertanto, il messaggio di successo conta i post esaminati, non necessariamente i record caricati. Questa discrepanza era separata dall’errore dovuto ai record troppo grandi.