我已经在网上找了很长时间才找到解决方案,但我似乎无法想出任何可行的方法。我正在构建一个包含三个ActiveRecord模型的网站的产品搜索。协会如下:
class NormalBrand < ApplicationRecord
has_many :normal_models
end
class NormalModel < ApplicationRecord
belongs_to :normal_brand
has_many :products
end
class Product < ApplicationRecord
belongs_to :normal_model
end
我已成功将ElasticSearch集成到我的rails应用程序中,但我似乎无法让搜索范围包含多个模型。目前,当我搜索时,搜索的唯一字段是Product类中的列。我想要搜索NormalBrand和NormalModels中的列。下面是我目前的Product类代码。我已经阅读了使用Tire的github上的示例,但我无法让它工作(https://github.com/elastic/elasticsearch-rails/blob/master/elasticsearch-model/examples/activerecord_associations.rb)。
require 'elasticsearch/model'
class Product < ApplicationRecord
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
#associations
belongs_to :category_model
belongs_to :normal_model
has_many :order_items
has_many :quote_items
#validations
validates :name, presence: true
validates :part_number, presence: true
validates :description, presence: true
validates :sku, presence: true
validates :sku, uniqueness: true
validates :price, presence: true
validates :price, numericality: { greater_than_or_equal_to: 0.0 }
validates :weight, presence: true
validates :weight, numericality: { greater_than_or_equal_to: 0.0 }
validates :url_key, presence: true
validates :url_key, uniqueness: true
#this is an overridden method.
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['name^10', 'text']
}
}
}
)
end
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :name, analyzer: 'english'
indexes :text, analyzer: 'english'
end
end
def as_indexed_json(options={})
as_json(
include: {
normal_model: { methods: [:name], only: [:name] }
}
)
end
#def to_param
# url_key
#end
end
Product.import force: true
第一次在我的控制器中调用Product.search函数
Processing by SearchController#search as HTML
Parameters: {"q"=>"PS300"}
Product Load (0.8ms) SELECT "products".* FROM "products" ORDER BY
"products"."id" ASC LIMIT $1 [["LIMIT", 1000]]
NormalModel Load (0.4ms) SELECT "normal_models".* FROM "normal_models"
WHERE "normal_models"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
CACHE (0.0ms) SELECT "normal_models".* FROM "normal_models" WHERE
"normal_models"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Rendering search/search.html.erb within layouts/application
Rendered search/search.html.erb within layouts/application (11.6ms)
Rendered layouts/_header.html.erb (4.3ms)
Rendered layouts/_flash_messages.html.erb (0.7ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 4797ms (Views: 4544.7ms | ActiveRecord: 8.7ms)
我第二次尝试搜索。
Started GET "/catalogsearch/result/?q=Nordictrack" for 50.255.94.246 at 2017-05-02 13:46:47 +0000
Cannot render console from 50.255.94.246! Allowed networks: 127.0.0.1, ::1,
127.0.0.0/127.255.255.255
Processing by SearchController#search as HTML
Parameters: {"q"=>"Nordictrack"}
Rendering search/search.html.erb within layouts/application
Rendered search/search.html.erb within layouts/application (176.3ms)
Rendered layouts/_header.html.erb (1.3ms)
Rendered layouts/_flash_messages.html.erb (0.6ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 239ms (Views: 237.2ms | ActiveRecord: 0.0ms)
我的搜索控制器
class SearchController < ApplicationController
def search
if params[:q].nil?
@products = []
else
@products = Product.search params[:q]
end
end
end
答案 0 :(得分:0)
在这种情况下:
def as_indexed_json(options={})
as_json(
include: {
normal_model: { methods: [:name], only: [:name] }
}
)
end
您应该为关联的模型添加嵌套索引:
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :name, analyzer: 'english'
indexes :text, analyzer: 'english'
indexes :normal_model, type: 'nested' do
indexes :name, analyzer: 'english'
end
end
end
并更改您的查询,如下所示:
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['normal_model.name^10', 'name^10', 'text']
}
}
}
)
end