假设我输入文本"电子书"进行搜索,得到以下结果:
Ebook for Rails
Elastic Ebook
Booking for ebook.
现在我从列表中选择"弹性电子书"。假设其他几个用户输入电子书进行搜索,其中大多数人从列表中选择"弹性电子书"。这清楚地表明了 Elastic 电子书作为关键词"电子书"的受欢迎程度。因此,在进一步的搜索中,我希望 Elastic 电子书具有更高的优先级并出现在顶部。
Elastic Ebook
Ebook for Rails
Booking for an ebook.
有什么办法可以做到这一点。
我的代码文档.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 什么是流行的(就在用户搜索并单击列表中的一个结果之后(,并通过更新它们将此信息存储在您的文档中。从技术上讲,更新意味着再次删除和插入文档,但可以使用更新 API 和脚本来完成。
有了这个,您可以使用function_score
查询进行按受欢迎程度提升的搜索:
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "Rental",
"fields": [ "name"]
}
},
"field_value_factor": {
"field": "popularity",
"modifier": "..."
}
}
}
}
其中popularity
是您更新的字段。
还可以将有关人口普鲁拉的信息存储在单独的文档中,并扩展查询以组合这两个信息源。
还有用于学习排名集成的插件,但我从未使用过它们,因此很难说集成有多复杂。