You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将pg_search_scope与Mobility结合实现多语言翻译属性搜索

实现方案

这个需求完全可以实现,你当前搜索返回空的核心原因是:pg_search默认会从categories主表查询name字段,但你使用Mobility的key_value后端时,所有翻译内容存储在独立的string_translations关联表中,主表不存在name字段,自然匹配不到结果。

具体修改步骤

1. 修改模型中的pg_search配置

调整pg_search_scope为动态参数形式,自动关联翻译表并按当前locale过滤匹配:

class Category < ApplicationRecord
  extend Mobility
  translates :name, type: :string

  include PgSearch::Model

  pg_search_scope :search,
    ->(query, locale = I18n.locale) {
      {
        associated_against: { string_translations: :value },
        using: {
          trigram: { threshold: 0.3, word_similarity: true }
        },
        # 过滤仅匹配当前语言、name属性的翻译记录
        conditions: -> { where(string_translations: { locale: locale, key: 'name' }) }
      }
    }
end

2. 调整控制器代码,统一预加载翻译避免N+1查询

def index
  @categories = params[:query].present? ? Category.search(params[:query]).includes(:string_translations) : Category.all.includes(:string_translations)
end

可选优化方案(性能更佳)

如果你的业务场景支持调整Mobility后端,可将key_value后端替换为column后端,直接在categories表新增name_en、name_de字段存储翻译,此时搜索配置会更简单,查询性能也更高:

修改后模型配置

class Category < ApplicationRecord
  extend Mobility
  translates :name, type: :string, backend: :column

  include PgSearch::Model

  pg_search_scope :search,
    ->(query, locale = I18n.locale) {
      {
        against: :"name_#{locale}",
        using: {
          trigram: { threshold: 0.3, word_similarity: true }
        }
      }
    }
end

这种方式无需关联翻译表,直接查询主表字段即可,适合数据量较大的场景。

内容的提问来源于stack exchange,提问作者axcr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 06:09:04