"Back to the Future ", "created_at"=>Wed, 03 Dec 2014-6ren">
gpt4 book ai didi

ruby-on-rails - Elasticsearch rails/Elasticsearch 模型搜索模型关联

转载 作者:行者123 更新时间:2023-11-29 02:50:16 26 4
gpt4 key购买 nike

我有一个名为 Movie 的模型,如下所示:

class Movie < ActiveRecord::Base
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks

has_many :actors, after_add: [ lambda {|a,c| a.__elasticsearch__.index_document}],
after_remove: [ lambda {|a,c| a.__elasticsearch__.index_document}]

settings index: {number_of_shards: 1} do
mappings dynamic: 'false' do
indexes :title, analyzer: 'snowball', boost: 100
indexes :actors
end
end

def as_indexed_json(options={})
self.as_json(
include: {
actors: { only: :name}
}
)
end
end

当我执行 Movie.first.as_indexed_json 时,我得到:

{"id"=>6, "title"=>"Back to the Future ", 
"created_at"=>Wed, 03 Dec 2014 22:21:24 UTC +00:00,
"updated_at"=>Fri, 12 Dec 2014 23:40:03 UTC +00:00,
"actors"=>[{"name"=>"Michael J Fox"}, {"name"=>"Christopher Lloyd"},
{"name"=>"Lea Thompson"}]}

但是当我执行 Movie.search("Christopher Lloyd").records.first 时,我得到:=> nil

我可以对索引进行哪些更改以搜索与搜索到的 Actor 相关的电影?

最佳答案

我使用过滤查询来解决这个问题,首先我创建了一个名为searchable.rbActiveSupport::Concern,concern看起来像这样:

module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks

index_name [Rails.application.engine_name, Rails.env].join('_')

settings index: { number_of_shards: 3, number_of_replicas: 0} do
mapping do
indexes :title, type: 'multi_field' do
indexes :title, analyzer: 'snowball'
indexes :tokenized, analyzer: 'simple'
end
indexes :actors, analyzer: 'keyword'
end
def as_indexed_json(options={})
hash = self.as_json()
hash['actors'] = self.actors.map(&:name)
hash
end

def self.search(query, options={})
__set_filters = lambda do |key, f|
@search_definition[:post_filter][:and] ||= []
@search_definition[:post_filter][:and] |= [f]
end

@search_definition = {
query: {},

highlight: {
pre_tags: ['<em class="label label-highlight">'],
post_tags: ['</em>'],
fields: {
title: {number_of_fragments: 0}
}
},
post_filter: {},

aggregations: {
actors: {
filter: {bool: {must: [match_all: {}]}},
aggregations: {actors: {terms: {field: 'actors'}}}
}
}
}

unless query.blank?
@search_definition[:query] = {
bool: {
should: [
{
multi_match: {
query: query,
fields: ['title^10'],
operator: 'and'
}
}
]
}
}
else
@search_definition[:query] = { match_all: {} }
@search_definition[:sort] = {created_at: 'desc'}
end

if options[:actor]
f = {term: { actors: options[:taxon]}}
end

if options[:sort]
@search_definition[:sort] = { options[:sort] => 'desc'}
@search_definition[:track_scores] = true
end
__elasticsearch__.search(@search_definition)
end
end
end

我在 models/concerns 目录中有上述问题。在 movies.rb 我有:

class Movie < ActiveRecord::Base
include Searchable
end

movies_controller.rb 中,我正在搜索 index 操作,操作如下所示:

def index 
options = {
actor: params[:taxon],
sort: params[:sort]
}
@movies = Movie.search(params[q], options).records
end

现在,当我转到 http://localhost:3000/movies?q=future&actor=Christopher 时,我得到了所有标题上有“ future ”一词并且有一个名叫克里斯托弗的 Actor 的记录.您可以拥有多个过滤器,如示例应用程序模板的 expert 模板所示 found here .

关于ruby-on-rails - Elasticsearch rails/Elasticsearch 模型搜索模型关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27582074/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com