我是 ElasticSearch 的新手,但需要使用它来返回产品列表。请不要包含引用已弃用的轮胎宝石的答案或旧答案的链接。
宝石文件
ruby '2.2.0'
gem 'rails', '4.0.3'
gem 'elasticsearch-model', '~> 0.1.6'
gem 'elasticsearch-rails', '~> 0.1.6'
我有几个有关系的模型。我包括了下面的关系。
模型和关系
product.rb 包括可搜索的
belongs_to :family
belongs_to :collection
has_many :benefits_products
has_many :benefits, :through => :benefits_products
def as_indexed_json(options={})
as_json(
include: {:benefits => { :only => [ :id, :name ] },
:categories => { :only => [ :id, :name ] } }
)
end
集合.rb
include Searchable
has_many :products
def as_indexed_json(options={})
as_json(
include: [:products]
)
end
家庭.rb
include Searchable
has_many :products
def as_indexed_json(options={})
as_json(
include: [:products]
)
end
福利.rb
include Searchable
has_many :benefits_products
has_many :products, :through => :benefits_products
def as_indexed_json(options={})
as_json(
include: [:products]
)
end
Serachable.rb 只是一个关注点,包括所有模型中的弹性搜索和回调
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
settings index: { number_of_shards: 1, number_of_replicas: 0 } do
mapping do
indexes :id, type: 'long'
indexes :name, type: 'string'
indexes :family_id, type: 'long'
indexes :collection_id, type: 'long'
indexes :created_at, type: 'date'
indexes :updated_at, type: 'date'
indexes :benefits, type: 'nested' do
indexes :id, type: 'long'
indexes :name, type: 'string'
end
indexes :categories, type: 'nested' do
indexes :id, type: 'long'
indexes :name, type: 'string'
end
end
end
def self.search(options={})
__set_filters = lambda do |key, f|
@search_definition[:filter][:and] ||= []
@search_definition[:filter][:and] |= [f]
end
@search_definition = {
query: {
filtered: {
query: {
match_all: {}
}
}
},
filter: {}
}
if options[:benefits]
f = { term: { "benefits.id": options[:benefits] } }
__set_filters.(:collection_id, f)
__set_filters.(:family_id, f)
__set_filters.(:categories, f)
end
def as_indexed_json(options={})
as_json(
include: {:benefits => { :only => [ :id, :name ] },
:categories => { :only => [ :id, :name ] } }
)
end
if options[:categories]
...
end
if options[:collection_id]
...
end
if options[:family_id]
...
end
__elasticsearch__.search(@search_definition)
end
end
end
弹性搜索
我将破折号分开的蛞蝓分为不同的家庭、收藏品和福利。我能够搜索具有特定系列或集合的产品并返回正确的结果。我也可以返回结果以获得一个好处,但它们似乎并不准确。搜索多种好处也会产生奇怪的结果。我想要所有字段搜索的“AND”组合,但我的结果似乎不是“AND”或“OR”的结果。所以这也让我感到困惑。
我应该将什么传递给 Product.search 方法以产生所需的结果?
感谢您的任何帮助,您可以提供!
编辑
我现在已经验证了产品的利益已被索引。我使用curl -XGET 'http://127.0.0.1:9200/products/_search?pretty=1'
它产生了一个看起来像这样的 json 响应:
{
"id":4,
"name":"product name"
"family_id":16
"collection_id":6
"created_at":"2015-04-13T12:49:42.000Z"
"updated_at":"2015-04-13T12:49:42.000Z"
"benefits":[
{"id":2,"name":"my benefit 2"},
{"id":6,"name":"my benefit 6"},
{"id":7,"name":"my benefit 7"}
],
"categories":[
{"id":2,"name":"category 2"}
]}
},
{...}
如果我想要上面的示例产品,现在我只需要弄清楚如何在 ElasticSearch 中搜索具有好处 2,6 和 7 的产品。我正在专门寻找提交给 elasticsearch #search 方法的语法,以获取嵌套“AND”查询、嵌套查询设置/映射的结果(以确保我没有遗漏任何内容,以及您可以想到的任何其他相关信息你们解决这个问题。
更新
Searchable 问题已更新以反映收到的答案。我翻译了映射 json 对象以适应 elasticsearch-model 语法。当我尝试以类似的方式翻译查询时,我剩下的困惑发生了。
第二次更新
我对 elasticsearch-rails 示例应用程序的searchable.rb 的大部分关注是基本的。我已经更新了 searchable.rb 以反映这段代码,当我得到结果时,它们不是“AND”执行的结果。当我应用两个好处时,我会从所有具有其中一个好处的产品中得到结果。