gpt4 book ai didi

ruby-on-rails - 如何使用 ElasticSearch-Rails 查询 dsl 返回相关关系

转载 作者:行者123 更新时间:2023-11-29 02:43:41 27 4
gpt4 key购买 nike

我是 ElasticSearch 的新手,但需要用它来返回产品列表。请不要包含引用已弃用轮胎 gem 的旧答案的答案或链接。

gem 文件

ruby '2.2.0'
gem 'rails', '4.0.3'
gem 'elasticsearch-model', '~> 0.1.6'
gem 'elasticsearch-rails', '~> 0.1.6'

我有几个有关系的模型。我包括以下关系。

模型和关系

产品.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

collection.rb

  include Searchable

has_many :products

def as_indexed_json(options={})
as_json(
include: [:products]
)
end

family.rb

  include Searchable

has_many :products

def as_indexed_json(options={})
as_json(
include: [:products]
)
end

benefit.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只是一个关注点,包括所有模型中的 Elastic 搜索和回调

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

Elasticsearch

我将鼻涕虫分解成不同的家族、收藏品和福利。我能够搜索具有特定系列或系列的产品并返回正确的结果。我也可以返回结果以获得一个好处,但它们似乎并不准确。搜索多个好处也会产生奇怪的结果。我想要所有字段搜索的“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”查询的结果、嵌套查询设置/映射(以确保我没有遗漏任何内容,以及您能想到的任何其他相关信息你们解决这个问题。

已更新

可搜索问题已更新以反射(reflect)收到的答案。我翻译了映射 json 对象以适应 elasticsearch-model 语法。当我尝试以类似的方式翻译查询时,我仍然感到困惑。

第二次更新

我基本上是我的 searchable.rb 关注点 the elasticsearch-rails example app .我已经更新了 searchable.rb 以反射(reflect)这段代码,虽然我得到了结果,但它们不是“AND”执行的结果。当我应用两个好处时,我会从所有具有其中一个好处的产品中获得结果。

最佳答案

默认情况下,如果您使用动态映射来加载数据,那么 ES 会将嵌套对象创建为平面对象,因此会松散各种嵌套属性之间的关系。为了保持适当的关系,我们可以使用 nested objectsparent-child关系。

现在我将使用嵌套对象来实现预期的结果:

映射:

PUT /index-3
{
"mappings": {
"products":{
"properties": {
"id": {
"type": "long"
},
"name":{
"type": "string"
},
"family_id":{
"type": "long"
},
"collection_id":{
"type": "long"
},
"created_at":{
"type": "date"
},
"updated_at":{
"type": "date"
},
"benefits":{
"type": "nested",
"include_in_parent": true,
"properties": {
"id": {
"type": "long"
},
"name":{
"type":"string"
}
}
},
"categories":{
"type": "nested",
"include_in_parent": true,
"properties": {
"id":{
"type": "long"
},
"name":{
"type":"string"
}
}
}
}
}
}
}

如果您观察到我已将子对象视为嵌套映射并包含在父对象中。

现在是一些示例数据:

PUT /index-3/products/4
{
"name":"product name 4",
"family_id":15,
"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"}
]
}
PUT /index-3/products/5
{
"name":"product name 5",
"family_id":16,
"collection_id":6,
"created_at":"2015-04-13T12:49:42.000Z",
"updated_at":"2015-04-13T12:49:42.000Z",
"benefits":[
{"id":5,"name":"my benefit 2"},
{"id":6,"name":"my benefit 6"},
{"id":7,"name":"my benefit 7"}
],
"categories":[
{"id":3,"name":"category 2"}
]
}
PUT /index-3/products/6
{
"name":"product name 6",
"family_id":15,
"collection_id":5,
"created_at":"2015-04-13T12:49:42.000Z",
"updated_at":"2015-04-13T12:49:42.000Z",
"benefits":[
{"id":5,"name":"my benefit 2"},
{"id":55,"name":"my benefit 6"},
{"id":7,"name":"my benefit 7"}
],
"categories":[
{"id":3,"name":"category 2"}
]
}

现在是查询部分:

GET index-3/products/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"terms": {
"benefits.id": [
5,6,7
],
"execution": "and"
}
}
}
}
}

产生以下结果:

{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "index-3",
"_type": "products",
"_id": "5",
"_score": 1,
"_source": {
"name": "product name 5",
"family_id": 16,
"collection_id": 6,
"created_at": "2015-04-13T12:49:42.000Z",
"updated_at": "2015-04-13T12:49:42.000Z",
"benefits": [
{
"id": 5,
"name": "my benefit 2"
},
{
"id": 6,
"name": "my benefit 6"
},
{
"id": 7,
"name": "my benefit 7"
}
],
"categories": [
{
"id": 3,
"name": "category 2"
}
]
}
}
]
}
}

在查询时,我们必须使用带有“and execution”的术语过滤器,以便它只检索包含所有术语的文档。

关于ruby-on-rails - 如何使用 ElasticSearch-Rails 查询 dsl 返回相关关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29564606/

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