Ruby on rails 带轮胎的Elasticsearch:带多个单词的edgeNgram
假设我有5部电影:Ruby on rails 带轮胎的Elasticsearch:带多个单词的edgeNgram,ruby-on-rails,
elasticsearch,tire,Ruby On Rails,
elasticsearch,Tire,假设我有5部电影: 圣索莱尔酒店 桑萨 这也是 索尔古德 唯一幸存者 我希望实现具有以下预期行为的自动完成搜索字段: “Sans”>Sans Soleil,Sansa “Sans so”>Sans Soleil “所以”>这也是,索尔·古德,唯一的幸存者 “如此”>这也是如此 “Sol”>Sol Goode,唯一幸存者,无太阳 这个用例看起来很明显,必须被很多人使用,但我就是不能让它正常工作,我似乎找不到任何答案或文档来帮助。这是我目前的型号: class Film < Media
- 圣索莱尔酒店
- 桑萨
- 这也是
- 索尔古德
- 唯一幸存者
- “Sans”>Sans Soleil,Sansa
- “Sans so”>Sans Soleil
- “所以”>这也是,索尔·古德,唯一的幸存者
- “如此”>这也是如此
- “Sol”>Sol Goode,唯一幸存者,无太阳
class Film < Media
include Tire::Model::Search
include Tire::Model::Callbacks
settings :analysis => {
:filter => {
:title_ngram => {
"type" => "edgeNGram",
"min_gram" => 2,
"max_gram" => 8,
"side" => "front" }
},
:analyzer => {
:title_analyzer => {
"tokenizer" => "lowercase",
"filter" => ["title_ngram"],
"type" => "custom" }
}
} do
mapping do
indexes :title, :type => 'string', :analyzer => 'title_analyzer'
indexes :int_english_title, :type => 'string', :analyzer => 'title_analyzer'
end
end
end
这会产生一些奇怪的行为:
- “Sans so”按顺序返回“Sansa,Sans Soleil,这也是”
- “返回”索尔·古德、无索莱尔、唯一的幸存者也是如此,这个“顺序”也是如此
search = Tire.search ['books', 'films', 'shows'], :load => true, :page => 1, :per_page => 10 do |s|
s.query do |q|
q.boolean do |b|
b.must {|m| m.string params[:search]}
end
end
end
我认为,如果查询设置为
类型:“短语前缀”
,您可能会得到想要的结果。大多数,但不是所有,你的例子都能奏效
使用Ngrams,您可以更好地控制流程,但它们的召回量相当大(它们通常会返回比您想要的更多的数据),您必须与之抗争。这是您在使用多个查询词(“Sans-so”)时观察到的“奇怪行为”,因为它们作为Sans或so
查询有效地执行
尝试使用default\u操作符:”和“
选项(参见轮胎),或者更确切地说,使用操作符:”和“
选项进行查询(参见轮胎)
有一些关于自动完成、轮胎和Ngrams的文章:
b.must{m | m.string”title:#{params[:search]}
是的,当我尝试得到与以前相同的结果时。@Salil不需要将查询包装在布尔查询中——这没有任何区别。另外,正如@gibson所指出的,不指定标题:
查询限定符将产生完全不正确的结果。在最新有趣的文章中,对同一问题采用不同的方法,你看过这一集吗?如果它解决了我的确切用例,因为它能够正确地对多个单词的标题进行NGRAM命中排序,我可能会考虑订阅。它不能解决您的确切问题,但使用了不同的方法。如果你为了钱开发rails应用程序,rails可以节省大量的时间,在我的例子中,我在每个月的第一天节省9美元。正如你正确指出的,处理空白是主要问题。我曾尝试使用default\u操作符:“和”
,但没有多大成功,但与类型匹配:“短语前缀”
似乎可以奏效!你知道为什么带有和的查询字符串不起作用吗?我还调整了每个索引的映射,以使用一个单独的:index\u analyzer
和:search\u analyzer
。除了你链接的文章之外,我还建议你阅读这篇文章,它彻底分解了搜索过程,让事情变得更清楚:使用“and”操作符,我认为“sans so”查询不应该返回“so Is this”--因为“sans”部分不会在“so Is this”中分解成任何ngram,除非我弄错了,match
的phrase\u前缀
类型对于简单的自动补全来说应该是非常好的。当然,如前所述,使用Ngrams,您可以获得更大的灵活性和更高的召回率。拆分索引
和搜索
分析器是一个好主意,因为您的查询不会被标记为Ngrams——这正是您想要的,一个人在您的网站上执行的查询已经是“伪ngrammed”,因为她只写“部分词语”。
search = Tire.search ['books', 'films', 'shows'], :load => true, :page => 1, :per_page => 10 do |s|
s.query do |q|
q.boolean do |b|
b.must {|m| m.string params[:search]}
end
end
end