Rails + PostgreSQL - 使用全文搜索的多关键字搜索
Rails + PostgreSQL - Multiple Keyword Search using Full Text Search
我在 Rails 应用 CookBook 上有一本简单的 Ruby,里面有食谱。我有 2 tables(食谱和配料)。一个食谱有很多成分。
我正在尝试实现一个简单的搜索框,以便我可以过滤包含某些成分的食谱....
这些是 table:
create table recipes (id int, recipe_name varchar(100));
create table ingredients(id int, ingredient_name varchar(100), recipe_id int);
insert into recipes values
(1, 'my recipe 1'),
(2, 'my recipe 2');
(3, 'my recipe 3');
(4, 'my recipe 4');
insert into ingredients values
(1, 'Banana', 1),
(2, 'Milk', 1),
(3, 'Banana', 2),
(4, 'Milk', 2),
(5, '4 ½ teaspoons baking powder', 2);
(6, '1 ½ cups whole wheat flour', 4),
(7, 'Heavy Cream', 4);
(8, '⅓ cup packed brown sugar', 3),
(9, 'Milk', 3);
(10, '2 teaspoons packed brown sugar', 4);
假设我在搜索框中输入了两种成分,例如“香蕉”和“牛奶”。然后我希望得到包含这些词的成分 table 行的食谱...
这是我 recipes_controller 中的代码 我目前有:
def search
if params[:search].blank?
redirect_to recipes_path and return
else
@parameter = params[:search].downcase
@recipe_ids = Ingredient.search_ingredient(@parameter).pluck(:recipe_id)
@results = Recipe.where(id: @recipe_ids).paginate(page: params[:page], per_page: 26)
end
end
ingredient.rb中的代码:
class Ingredient < ApplicationRecord
belongs_to :recipe
include PgSearch::Model
pg_search_scope :search_ingredient,
against: { ingredient_name: 'A' },
using: {
tsearch: {
dictionary: 'english', tsvector_column: 'searchable'
}
}
end
这个问题是,如果我在搜索框中输入 'Banana milk',我将不会在结果集中得到任何东西,因为它们在配料 table 中的单独行中,属于一个食谱.在这种情况下,我应该至少获得 ID 为 1 和 2 的食谱,因为它们都有这些成分
如果我只搜索一种成分,比如“牛奶”,那么我会得到包含该成分的所有食谱。
我该如何完成?
提前致谢
我建议您使用 any_word
属性,请查看此处的文档 - https://github.com/Casecommons/pg_search#any_word
pg_search_scope :search_ingredient,
against: { ingredient_name: 'A' },
using: {
tsearch: {
any_word: true,
dictionary: 'english',
tsvector_column: 'searchable'
}
}
我在 Rails 应用 CookBook 上有一本简单的 Ruby,里面有食谱。我有 2 tables(食谱和配料)。一个食谱有很多成分。
我正在尝试实现一个简单的搜索框,以便我可以过滤包含某些成分的食谱....
这些是 table:
create table recipes (id int, recipe_name varchar(100));
create table ingredients(id int, ingredient_name varchar(100), recipe_id int);
insert into recipes values
(1, 'my recipe 1'),
(2, 'my recipe 2');
(3, 'my recipe 3');
(4, 'my recipe 4');
insert into ingredients values
(1, 'Banana', 1),
(2, 'Milk', 1),
(3, 'Banana', 2),
(4, 'Milk', 2),
(5, '4 ½ teaspoons baking powder', 2);
(6, '1 ½ cups whole wheat flour', 4),
(7, 'Heavy Cream', 4);
(8, '⅓ cup packed brown sugar', 3),
(9, 'Milk', 3);
(10, '2 teaspoons packed brown sugar', 4);
假设我在搜索框中输入了两种成分,例如“香蕉”和“牛奶”。然后我希望得到包含这些词的成分 table 行的食谱...
这是我 recipes_controller 中的代码 我目前有:
def search
if params[:search].blank?
redirect_to recipes_path and return
else
@parameter = params[:search].downcase
@recipe_ids = Ingredient.search_ingredient(@parameter).pluck(:recipe_id)
@results = Recipe.where(id: @recipe_ids).paginate(page: params[:page], per_page: 26)
end
end
ingredient.rb中的代码:
class Ingredient < ApplicationRecord
belongs_to :recipe
include PgSearch::Model
pg_search_scope :search_ingredient,
against: { ingredient_name: 'A' },
using: {
tsearch: {
dictionary: 'english', tsvector_column: 'searchable'
}
}
end
这个问题是,如果我在搜索框中输入 'Banana milk',我将不会在结果集中得到任何东西,因为它们在配料 table 中的单独行中,属于一个食谱.在这种情况下,我应该至少获得 ID 为 1 和 2 的食谱,因为它们都有这些成分
如果我只搜索一种成分,比如“牛奶”,那么我会得到包含该成分的所有食谱。
我该如何完成?
提前致谢
我建议您使用 any_word
属性,请查看此处的文档 - https://github.com/Casecommons/pg_search#any_word
pg_search_scope :search_ingredient,
against: { ingredient_name: 'A' },
using: {
tsearch: {
any_word: true,
dictionary: 'english',
tsvector_column: 'searchable'
}
}