Ruby on rails 为什么此elasticsearch/tire代码与部分单词不匹配?
我正在尝试使用Elasticsearch和Tire索引一些数据。我希望能够搜索部分匹配,而不仅仅是完整的单词。在下面的示例模型上运行查询时,它将只匹配“notes”字段中与单词完全匹配的单词。我不明白为什么Ruby on rails 为什么此elasticsearch/tire代码与部分单词不匹配?,ruby-on-rails,elasticsearch,tire,Ruby On Rails,elasticsearch,Tire,我正在尝试使用Elasticsearch和Tire索引一些数据。我希望能够搜索部分匹配,而不仅仅是完整的单词。在下面的示例模型上运行查询时,它将只匹配“notes”字段中与单词完全匹配的单词。我不明白为什么 class Thingy include Tire::Model::Search include Tire::Model::Callbacks # has some attributes tire do settings analysis: { fil
class Thingy
include Tire::Model::Search
include Tire::Model::Callbacks
# has some attributes
tire do
settings analysis: {
filter: {
ngram_filter: {
type: 'nGram',
min_gram: 2,
max_gram: 12
}
},
analyzer: {
index_ngram_analyzer: {
type: 'custom',
tokenizer: 'standard',
filter: ['lowercase']
},
search_ngram_analyzer: {
type: 'custom',
tokenizer: 'standard',
filter: ['lowercase', 'ngram_filter']
}
}
} do
mapping do
indexes :notes, :type => "string", boost: 10, index_analyzer: "index_ngram_analyzer", search_analyzer: "search_ngram_analyzer"
end
end
end
def to_indexed_json
{
id: self.id,
account_id: self.account_id,
created_at: self.created_at,
test: self.test,
notes: some_method_that_returns_string
}.to_json
end
end
查询如下所示:
@things = Thing.search page: params[:page], per_page: 50 do
query {
boolean {
must { string "account_id:#{account_id}" }
must_not { string "test:true" }
must { string "#{query}" }
}
}
sort {
by :id, 'desc'
}
size 50
highlight notes: {number_of_fragments: 0}, options: {tag: '<span class="match">'}
end
@things = Thing.search page: params[:page], per_page: 50 do
query {
match [:prop_1, prop_2, :notes], query
}
sort {
by :id, 'desc'
}
filter :term, account_id: account_id
filter :term, test: false
size 50
highlight notes: {number_of_fragments: 0}, options: {tag: '<span class="match">'}
end
我做错了什么?你差一点就到了!:)事实上,问题是您已经交换了index\u analyzer
和search\u analyzer
的角色
让我简单解释一下它是如何工作的:
Martian
之类的单词编制索引时,它会被分解为:['ma'、'mar'、'mart'、…、'ar'、'art'、'arti'、…]
。您可以使用Analyze API进行尝试:http://localhost:9200/thingies/_analyze?text=Martian&analyzer=index_ngram_analyzer
index\u analyzer
和search\u analyzer
分开的原因,因此Elasticsearch知道如何在索引过程中分析notes
属性,以及如何针对该属性分析任何搜索短语analyzer: {
index_ngram_analyzer: {
type: 'custom',
tokenizer: 'standard',
filter: ['lowercase', 'ngram_filter']
},
search_ngram_analyzer: {
type: 'custom',
tokenizer: 'standard',
filter: ['lowercase']
}
}
完整的、有效的Ruby代码如下。另外,我强烈建议您迁移到新的Rubygem,它包含轮胎的所有重要功能,并且正在积极开发中
我的问题是,我使用的是
字符串
查询,而不是匹配
查询。搜索应该这样写:
@things = Thing.search page: params[:page], per_page: 50 do
query {
boolean {
must { string "account_id:#{account_id}" }
must_not { string "test:true" }
must { string "#{query}" }
}
}
sort {
by :id, 'desc'
}
size 50
highlight notes: {number_of_fragments: 0}, options: {tag: '<span class="match">'}
end
@things = Thing.search page: params[:page], per_page: 50 do
query {
match [:prop_1, prop_2, :notes], query
}
sort {
by :id, 'desc'
}
filter :term, account_id: account_id
filter :term, test: false
size 50
highlight notes: {number_of_fragments: 0}, options: {tag: '<span class="match">'}
end
@things=Thing.search页面:参数[:page],每页:50 do
质疑{
匹配[:属性1,属性2,:注释],查询
}
分类{
作者:id,“desc”
}
筛选器:术语、帐户\u id:帐户\u id
筛选器:术语,测试:false
50码
突出显示注释:{u片段的数量:0},选项:{tag:''}
结束
在更改映射时,请确保重新为文档编制索引,并仅尝试对注释
字段进行一次查询。另外,account\u id
等上的所有字符串查询都应该在过滤查询中进行过滤。是的,我每次都在重新编制索引。谢谢你提醒我有关过滤器的事!我去看看。但它实际上应该仍然按原来的方式工作,对吗?实际上这也不起作用。我清除了索引并重新导入测试,它停止了工作。真的不知道发生了什么。