Ruby on rails ElasticSearch:将查询字符串与术语过滤器相结合
我在rails项目中使用tire和elasticsearch,这是一个汽车零件零售网站。ES正在为用于浏览零件目录的分面搜索页面供电。我的问题是:如何使术语过滤器在使用查询字符串搜索相同字段时仅返回精确匹配,而仅对查询字符串使用分析器? 我希望这是有道理的。我将尝试提供一个例子: 所讨论的模型/索引称为部件。假设零件具有称为Ruby on rails ElasticSearch:将查询字符串与术语过滤器相结合,ruby-on-rails,
elasticsearch,tire,Ruby On Rails,
elasticsearch,Tire,我在rails项目中使用tire和elasticsearch,这是一个汽车零件零售网站。ES正在为用于浏览零件目录的分面搜索页面供电。我的问题是:如何使术语过滤器在使用查询字符串搜索相同字段时仅返回精确匹配,而仅对查询字符串使用分析器? 我希望这是有道理的。我将尝试提供一个例子: 所讨论的模型/索引称为部件。假设零件具有称为类别和子类别的映射。如果用户选择制动器类别和制动卡钳托架子类别(创建术语过滤器),我必须确保不会返回制动卡钳子类别中的零件–这是一个单独的子类别。但是,我确实希望用户能够简单
类别
和子类别
的映射。如果用户选择制动器类别和制动卡钳托架子类别(创建术语过滤器),我必须确保不会返回制动卡钳子类别中的零件–这是一个单独的子类别。但是,我确实希望用户能够简单地在搜索字段中输入“brakes”之类的内容(创建查询字符串),并从所有这些类别的产品中获取结果
以下是零件模型中的相关代码:
def to_indexed_json
fits = fitments.try(:map) do |fit|
{
make: fit.try(:make).try(:name),
make_id: fit.try(:make).try(:id),
model: fit.try(:model).try(:name),
model_id: fit.try(:model).try(:id),
year: fit.year,
sub_model: fit.sub_model
}
end
{
id: id,
name: name,
description: description,
fitments: fits,
categories: root_categories,
sub_categories: sub_categories,
price: price,
condition_id: condition_id,
country_of_origin: country_of_origin,
brand: brand,
oem: oem,
thumb_url: part_images.first.try(:image).try(:thumb).try(:url),
city: user.try(:city),
inventory: inventory,
part_number: part_number,
user: user.try(:public_name)
}.to_json
end
mapping do
indexes :id, type: 'integer'
indexes :name, analyzer: 'snowball', boost: 40
indexes :description, analyzer: 'snowball', boost: 12
indexes :price, type: "integer"
indexes :country_of_origin, index: :not_analyzed
indexes :condition_id, type: "integer"
indexes :brand, index: :not_analyzed
indexes :oem, type: "boolean"
indexes :city, index: :not_analyzed
indexes :inventory, type: "integer"
indexes :part_number, index: :not_analyzed
indexes :user, index: :not_analyzed
indexes :thumb_url, index: :not_analyzed
indexes :fitments do
indexes :make
indexes :make_id, type: "integer" #, index: 'not_analyzed'
indexes :model
indexes :model_id, type: "integer" #, index: 'not_analyzed'
indexes :year, type: "integer"
indexes :sub_model
end
indexes :categories do
indexes :name, index: :not_analyzed
indexes :id, type: "integer"
end
indexes :sub_categories do
indexes :name, index: :not_analyzed
indexes :id, type: "integer"
end
end
def search(params={})
query_filters = []
tire.search(:page => params[:page], :per_page => 20) do
query_filters << { :term => { 'fitments.make_id' => params[:make] }} if params[:make].present?
query_filters << { :term => { 'fitments.model_id' => params[:model] }} if params[:model].present?
query_filters << { :term => { 'categories.name' => params[:category] }} if params[:category].present?
query_filters << { :term => { 'sub_categories.name' => params[:sub_category] }} if params[:sub_category].present?
query_filters << { :term => { 'city' => params[:city] }} if params[:city].present?
query_filters << { :term => { 'condition_id' => params[:condition] }} if params[:condition].present?
query_filters << { :term => { 'brand' => params[:brand] }} if params[:brand].present?
query_filters << { :term => { 'oem' => params[:oem] }} if params[:oem].present?
query do
filtered do
query {
if params[:query].present?
string params[:query]
else
all
end
}
filter :and, query_filters unless query_filters.empty?
end
end
facet("categories") { terms 'categories.name', size: 50 } unless params[:category].present?
facet("cities") { terms 'city', size: 50 } unless params[:city].present?
if params[:category].present? && !params[:sub_category].present?
facet("sub_categories") { terms 'sub_categories.name', size: 50 }
end
facet("condition_id") { terms 'condition_id', size: 50 } unless params[:condition].present?
facet("brand") { terms 'brand', size: 50 } unless params[:brand].present?
facet("oem") { terms 'oem', size: 2 } unless params[:oem].present?
size params[:size] if params[:size]
end
end
def to_index_json
适合=适合。尝试(:map)适合|
{
make:fit.try(:make)。try(:name),
make_id:fit.try(:make.try(:id),
model:fit.try(:model)。try(:name),
model_id:fit.try(:model.try(:id),
年份:fit.year,
sub_模型:fit.sub_模型
}
结束
{
id:id,
姓名:姓名,,
描述:描述,
配件:适合,
类别:根类别,
子类别:子类别,
价格:价格,
条件id:条件id,
原产国:原产国,
品牌:品牌,,
oem:oem,
thumb\u url:part\u images.first.try(:image)。try(:thumb)。try(:url),
城市:用户。请尝试(:城市),
存货:存货,
零件号:零件号,
user:user.try(:public\u name)
}.to_json
结束
映射do
索引:id,类型:“整数”
索引:name,分析器:'snowball',boost:40
索引:描述,分析器:“雪球”,增强:12
索引:价格,类型:“整数”
索引:原产国,索引::未分析
索引:条件_id,类型:“整数”
索引:品牌,索引::未分析
索引:oem,类型:“布尔”
索引:城市,索引::未分析
索引:库存,类型:“整数”
索引:零件号,索引::未分析
索引:用户,索引::未分析
索引:thumb\u url,索引::未分析
索引:家具做什么
索引:make
索引:make_id,键入:“integer”#,索引:“not_analysis”
索引:模型
索引:model_id,键入:“integer”#,索引:“not_analysis”
索引:年份,类型:“整数”
索引:sub_模型
结束
索引:类别做什么
索引:名称,索引::未分析
索引:id,类型:“整数”
结束
索引:子类
索引:名称,索引::未分析
索引:id,类型:“整数”
结束
结束
def搜索(参数={})
查询过滤器=[]
搜索(:page=>params[:page],:per_page=>20)do
查询_筛选器{'fittments.make_id'=>params[:make]}如果params[:make]。是否存在?
查询_筛选器{'fittments.model_id'=>params[:model]}如果params[:model]。是否存在?
查询_筛选器{'categories.name'=>params[:category]}如果params[:category]。是否存在?
如果params[:sub_category],则查询_筛选器{'sub_categories.name'=>params[:sub_categories]}是否存在?
查询过滤器{'city'=>params[:city]}如果params[:city]。是否存在?
如果params[:condition],则查询{'condition\u id'=>params[:condition]}}。是否存在?
查询过滤器{'brand'=>params[:brand]}如果params[:brand]。是否存在?
如果参数为[:oem],则查询过滤器{'oem'=>params[:oem]}}是否存在?
询问
过滤do
质疑{
如果参数[:查询]。是否存在?
字符串参数[:查询]
其他的
全部的
结束
}
筛选器:和,除非query\u filters.empty,否则query\u filters.empty?
结束
结束
facet(“categories”){terms'categories.name',size:50}除非参数[:categories]。是否存在?
刻面(“城市”){术语“城市”,大小:50}除非参数[:城市]。是否存在?
如果参数[:类别]。是否存在?&&!参数[:子类别]。是否存在?
刻面(“子类别”){terms'sub_categories.name',大小:50}
结束
facet(“condition_id”){terms'condition_id',size:50}除非参数[:condition]。是否存在?
刻面(“品牌”){术语“品牌”,尺寸:50}除非参数[:品牌]。是否存在?
刻面(“oem”){术语“oem”,大小:2}除非参数[:oem]。是否存在?
大小参数[:大小]如果参数[:大小]
结束
结束
您必须在未分析的字段上使用Elasticsearch和filter的功能;参见示例。谢谢karmi。这是一个巨大的帮助,你在这里如此支持你的宝石!