整合pagy和meilisearch实现分页搜索到Rails

Integrate pagy and meilisearch for pagination and search in to Rails

如果我已经在使用 Pagy,那么将 pagy_search 集成到我的索引中的最佳方式是什么?在我的控制器中,我目前有:

def index

    @gold_drivers = Driver.gold_plan
    @silver_drivers = Driver.silver_plan
    @free_drivers = Driver.free_plan

    @pagy, @drivers = pagy_array(
      @gold_drivers + @silver_drivers + @free_drivers,
      page: params[:page],
      items: 16
    )

    if params[:query].present?
      @drivers = @gold_drivers + @silver_drivers + @free_drivers
      drivers_search = Driver.pagy_search(params[:query])
      @pagy, @drivers = pagy_meilisearch(drivers_search, items: 25, page: params[:page])
    end
end

我有一个 Driver 模型,它委托给 Profile 模型。不幸的是,当我点击搜索时,我得到

Driver#first_name delegated to profile.first_name, but profile is nil: #<Driver id: 224... 据我所知,此驱动程序没有配置文件,但查询 运行 for @gold_drivers = Driver.gold_plan / @silver_drivers = Driver.silver_plan 等不应该 select 没有配置文件的驱动程序。

Driver.gold_plan后面的查询是:

find_by_sql("SELECT drivers.*, (profiles.no_races + profiles.no_poles + profiles.no_podiums + profiles.no_wins) AS scores FROM drivers INNER JOIN profiles ON profiles.driver_id = drivers.id INNER JOIN subscriptions ON subscriptions.driver_id = drivers.id WHERE subscriptions.status = 'active' AND profiles.first_name != null OR profiles.first_name != '' AND subscriptions.stripe_plan = '#{ENV["GOLD_ANNUAL"]}' OR subscriptions.stripe_plan = '#{ENV["GOLD_MONTH"]}' GROUP BY scores, drivers.id ORDER BY scores DESC")

在该查询中,我使用了 "AND profiles.first_name != null OR profiles.first_name != ''",它在 pagy_page 部分有效 - 但在 pagy_search 部分无效。

对此的任何指导表示赞赏!

首先:您的代码效率极低,因为:

  1. 它执行 3 个查询而不是 1 个
  2. 它将所有记录拉入内存(可能会使您的服务器崩溃)并使用更多内存将它们连接到一个数组中以创建另一个可能很大的对象
  3. 它使用pagy_array,即should never be used that way

所以让我们开始改变它。

  1. 不要使用 +,而是创建一个将 3 个范围(金、银、计划)OR 在一起的范围(这也应该是 AR 关系,而不是文字查询)。这将为您提供一个单一的 AR 关系,尚未将任何内容加载到内存中
  2. 直接将 AR 关系与 pagy 一起使用,而不是 pagy_array:这将只提取您需要的记录页面,而不是您不需要的所有记录需要
  3. pagy_meilisearch 使用相同的 AR 关系,您的问题可能会在没有进一步更改的情况下消失。如果不行,请查看您的示波器。