如何使用 rails 根据 Elastic 搜索中的用户选择提高特定搜索结果的排名
How can I increase the rank for a particular search result based on user selection in Elastic search using rails
假设我输入文本 "Ebook" 进行搜索并得到以下结果:
Ebook for Rails
Elastic Ebook
Booking for ebook.
现在我从列表中 select "Elastic Ebook"。假设其他几个用户输入了电子书进行搜索,其中大多数来自列表 select "Elastic Ebook"。这清楚地表明了关键词 "Ebook" 的 Elastic 电子书的受欢迎程度。因此,在进一步的搜索中,我希望 Elastic Ebook 具有更高的优先级并出现在顶部。
Elastic Ebook
Ebook for Rails
Booking for an ebook.
有什么办法可以实现吗
我的代码 document.rb :
require 'elasticsearch/model'
class Document < ApplicationRecord
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
belongs_to :user
Document.import force: true
def self.search(query)
__elasticsearch__.search({
query: {
multi_match: {
query: query,
fields: ['name^10', 'service'],
fuzziness: "AUTO"
}
}
})
end
settings index: {
"number_of_shards": 1,
analysis: {
analyzer: {
edge_ngram_analyzer: { type: "custom", tokenizer: "standard", filter:
["lowercase", "edge_ngram_filter", "stop", "kstem" ] },
}
},
filter: {
edge_ngram_filter: { type: "edgeNGram", min_gram: "3",
max_gram: "20" }
}
} do
mapping do
indexes :name, type: "string", analyzer: "edge_ngram_analyzer"
indexes :service, type: "string", analyzer: "edge_ngram_analyzer"
end
end
end
搜索控制器代码:
def search
if params[:query].nil?
@documents = []
else
@documents = Document.search params[:query]
end
end
对此没有简单的解决方案。 Elasticsearch 不知道您的用户在应用程序中选择了什么。
在最简单的方法中,您必须负责告诉 elasticesearch 什么是流行的(在用户搜索并单击列表中的一个结果之后),并通过更新将此信息存储在您的文档中。从技术上讲,更新意味着再次删除和插入文档,但可以使用 Update API 和脚本来完成。
有了这个,您可以使用 function_score
查询来搜索 boosting-by-popularity:
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "Rental",
"fields": [ "name"]
}
},
"field_value_factor": {
"field": "popularity",
"modifier": "..."
}
}
}
}
其中 popularity
是您更新的字段。
也可以将有关人口数量的信息存储在单独的文档中,并扩展查询以组合这两个信息源。
也有 Learning to Rank 集成的插件,但我从来没有使用过它们,所以很难说集成有多复杂。
假设我输入文本 "Ebook" 进行搜索并得到以下结果:
Ebook for Rails
Elastic Ebook
Booking for ebook.
现在我从列表中 select "Elastic Ebook"。假设其他几个用户输入了电子书进行搜索,其中大多数来自列表 select "Elastic Ebook"。这清楚地表明了关键词 "Ebook" 的 Elastic 电子书的受欢迎程度。因此,在进一步的搜索中,我希望 Elastic Ebook 具有更高的优先级并出现在顶部。
Elastic Ebook
Ebook for Rails
Booking for an ebook.
有什么办法可以实现吗
我的代码 document.rb :
require 'elasticsearch/model'
class Document < ApplicationRecord
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
belongs_to :user
Document.import force: true
def self.search(query)
__elasticsearch__.search({
query: {
multi_match: {
query: query,
fields: ['name^10', 'service'],
fuzziness: "AUTO"
}
}
})
end
settings index: {
"number_of_shards": 1,
analysis: {
analyzer: {
edge_ngram_analyzer: { type: "custom", tokenizer: "standard", filter:
["lowercase", "edge_ngram_filter", "stop", "kstem" ] },
}
},
filter: {
edge_ngram_filter: { type: "edgeNGram", min_gram: "3",
max_gram: "20" }
}
} do
mapping do
indexes :name, type: "string", analyzer: "edge_ngram_analyzer"
indexes :service, type: "string", analyzer: "edge_ngram_analyzer"
end
end
end
搜索控制器代码:
def search
if params[:query].nil?
@documents = []
else
@documents = Document.search params[:query]
end
end
对此没有简单的解决方案。 Elasticsearch 不知道您的用户在应用程序中选择了什么。
在最简单的方法中,您必须负责告诉 elasticesearch 什么是流行的(在用户搜索并单击列表中的一个结果之后),并通过更新将此信息存储在您的文档中。从技术上讲,更新意味着再次删除和插入文档,但可以使用 Update API 和脚本来完成。
有了这个,您可以使用 function_score
查询来搜索 boosting-by-popularity:
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "Rental",
"fields": [ "name"]
}
},
"field_value_factor": {
"field": "popularity",
"modifier": "..."
}
}
}
}
其中 popularity
是您更新的字段。
也可以将有关人口数量的信息存储在单独的文档中,并扩展查询以组合这两个信息源。
也有 Learning to Rank 集成的插件,但我从来没有使用过它们,所以很难说集成有多复杂。