我在我的rails 4应用程序中创建了一个搜索引擎,它运行良好,但我很难让asciifolding过滤器工作。我的模型有很多带有重音的术语,除非它们拼写正确,否则不会出现,即:我想搜索“Rodriguez”以显示“Rodríguez”的结果。我试图遵循许多不同的例子,但出于某种原因,当我使用以下代码重置我的数据库时,搜索根本不起作用(我没有收到错误,但无论查询是什么都没有出现)。
这是我的模特:
class Product < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
settings :analysis => {
:analyzer => {
:default => {
:tokenizer => "standard",
:filter => ["standard", "asciifolding"]
}
}
} do
mapping do
indexes :id, type: 'integer', index: :not_analyzed
indexes :name, boost: 5, analyzer: 'default'
indexes :website, index: :not_analyzed
indexes :price, type: 'integer', index: :not_analyzed
indexes :artist, boost: 3, analyzer: 'default'
indexes :company, boost: 4, analyzer: 'default'
indexes :date, type: 'date', index: :not_analyzed
end
end
def self.search(params)
tire.search(page: params[:page], per_page: 12) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
end
end
在测试之前,我用以下内容清除数据库:
rake db:setup
然后我跑:
rake environment tire:import CLASS=Product FORCE=true
我已经查看过许多不同的资源,包括弹性搜索和轮胎文档,但无论出于何种原因(我预计会有一个愚蠢的错误),它根本行不通。小注意,为了填充我的数据库我一直在导入一个csv文件,但我不明白为什么这会影响任何东西,特别是考虑到这个形式的搜索中没有任何东西出现(当我删除时,它的工作正常没有重音问题设置部分,只有映射块和搜索方法)。我是否需要调用某种Tire.index并导入?任何帮助表示赞赏!
更新
所以我对搜索查询进行了编辑,修复了问题,但提出了一个新问题:
def self.search(params)
tire.search(page: params[:page], per_page: 12) do
query { string params[:query], analyzer: :search_analyzer, :default_field => 'name' } if params[:query].present?
end
end
通过识别默认字段,我现在可以搜索重音不可知,但现在我的搜索仅限于名称,我无法接收之前工作的其他索引属性的结果。有谁知道如何设置多个默认字段?
答案 0 :(得分:0)
这是我在制作中使用的示例。对你的问题不解决,但它会让你开始。我的代码使用ICU plugin icu_folding,shingle_filter,multi_field和Tire。另请注意,自2013年9月起Tire为retired,如果是新项目,您应该使用elasticsearch-ruby或elasticsearch-rails。使用此代码,我可以使用Rod
查找Rodríguez
等案例进行自动填充。
class Profile
# ...
include Tire::Model::Persistence
# I'm also using ES as persistance storage.
include Tire::Model::DynamicPersistence
property :title, analyzer: 'snowball', type: :multi_field,
fields: {
title: {
type: 'string',
boost: 20.0,
search_analyzer: "autocomplete_search_analyzer",
index_analyzer: "autocomplete_indexer_analyzer"
},
completed: {
type: 'string',
boost: 15.0,
search_analyzer: "autocomplete_search_analyzer",
index_analyzer: "autocomplete_indexer_analyzer"
}
}
CONFIGURATION = {
settings: {
analysis: {
analyzer: {
shingle_analyzer: {
tokenizer: "keyword",
filter: ["icu_folding", "lowercase", "shingle_filter"]
},
sx_index_analyzer: {
tokenizer: "standard",
filter: ["icu_folding", "lowercase"]
},
sx_search_analyzer: {
tokenizer: "standard",
filter: ["icu_folding", "lowercase"]
}
},
filter: {
shingle_filter: {
type: "shingle",
min_shingle_size: 2,
max_shingle_size: 5
}
}
}
},
mappings: {
profile: {
"_all" => {
enabled: true,
index_analyzer: "sx_index_analyzer",
search_analyzer: "sx_search_analyzer"
},
properties: {
title: {
type: "multi_field",
fields: {
title: {
type: "string",
store: "yes",
boost: 20.0
#index_analyzer: "sx_index_analyzer",
#search_analyzer: "sx_search_analyzer"
},
sortable: {
type: "string",
index: "analyzed"
},
autocomplete: {
type: "string",
index_analyzer: "shingle_analyzer",
boost: 15.0
},
}
}
}
}
}
}
def self.rebuild_index
Tire.index Profile.index_name do
delete if Profile.index.exists?
create Profile::CONFIGURATION
end
end
end
希望它有所帮助!