ruby-on-railselasticsearchopensearchsearchkick

How to avoid N+1 when reindexing models with Searchkick


I am using searchkick to wrap OpenSearch. My Program model has this search_data:

{
  name: name,
  description: description,
  provider_name: provider.name,
  category: category&.name,
  age_min: age_min || 0,
  age_max: age_max || 999,
  start_dates: current_published_schedules.pluck(:start_date),
  zipcode: address&.zipcode,
  program_type: program_type
}

When I run the reindex task:

Program.reindex(refresh: true)

I see in the logs that many SQL queries for Provider and Schedule have been made, one for each Program. Is there a way to tell Searchkick to "includes" or "preload" somehow to optimize the reindexing?


Solution

  • Thankfully, the eager load method is available in Searchkick. We can use includes with the help of the search_import method

    You can refer more about on searchkick documentation here.

    From the sample data above, I noticed that your Program table has has_one associations with Provider, Category, etc. Using that, I’ve provided some sample examples below. I hope they are helpful to you.

    Program Model

    From inside of model you need to write as

    scope :search_import, -> { includes(:provider, :category, :current_published_schedules) }
    

    Now When you hit the reindex, it first eager loads the all association data what you have mentioned in search import. Now it continuously fires the single query for each program data to update in elastic.

    Hope this helps to fix your issue :)