Rails 在jsonb多个where条件下查找子串

Rails find substring in jsonb multiple where conditions

假设我的 table recipes 列类型为 ingredientsjsonb。 示例记录:

{
  id: 1,
  ingredients: [
    'eggs',
    'fragrant bread',
    'fresh tomatoes'
  ]
}

如何在where条件下检索带子字符串的记录? 例如:

ingredients = ['egg', 'tomato']
Recipe.where('ingredients ?& array[:keys]', keys: ingredients)

我正在尝试:

ingredients = ['egg', 'tomato']
Recipe.where("ingredients @> ARRAY[?]::varchar[]", ingredients).count

但是我收到这个错误:

ERROR:  operator does not exist: jsonb @> character varying[] (PG::UndefinedFunction)

我真的会考虑只使用两个表来代替,因为这让人讨厌 JSON 反模式。

class Recipe
  has_many :recipe_ingredients
  has_many :recipes, through: :recipe_ingredients

  def self.with_ingredients(*ingredients)
    binds = Array.new(ingredients.length, '?')
    sql = "ingredients.name ILIKE ANY(ARRAY[#{binds.join(,)}])"
    joins(:ingredients)
      .where(
        sql,
        *ingredients.map { |i| "'%#{i}%'" }
      )
  end
end
class RecipeIngredient
  belongs_to :ingredient
  belongs_to :recipe
end
class Ingredient
  has_many :recipe_ingredients
  has_many :recipes: through: :recipe_ingredients
end

这让您可以在 recipies.name 上使用有效的索引,合理的查询并避免非规范化。