如何使用 Searchkick 和 Rails 处理嵌套文档?
How to handle nested documents with Searchkick and Rails?
我有 equity_contracts
table 其中有一个 user_contract
和许多 prices
。 EquityContract
模型看起来像:
class EquityContract < ActiveRecord::Base
validates_presence_of :ticker, :name, :country, :currency
has_one :user_contract, as: :contract
has_many :prices
searchkick
scope :search_import, -> { includes(:user_contract, :prices) }
def search_data
{
name: name,
ticker: ticker,
country: country,
user_id: user_contract.try(:user_id),
prices: prices.map do |price|
{
traded_on: price.traded_on.to_s,
close: price.close
}
end
}
end
end
UserContract
看起来像:
class UserContract < ActiveRecord::Base
belongs_to :user
belongs_to :contract, polymorphic: true
end
现在我想索引 EquityContract
中的键 (name
, ticker
,country
,user_id
,prices
) 所以我运行EquityContract.reindex
。
现在,当我尝试做类似 equity = EquityContract.search "APPL_US"
的事情时,我得到 Searchkick::Results
看起来像这样的对象:
[24] pry(main)> equity = EquityContract.search "APPL_US", limit: 1
ETHON: performed EASY effective_url=http://127.0.0.1:9200/equity_contracts_development/_search response_code=200 return_code=ok total_time=0.101687
EquityContract Search (109.5ms) curl http://127.0.0.1:9200/equity_contracts_development/_search?pretty -d '{"query":{"dis_max":{"queries":[{"match":{"_all":{"query":"APPL_US","operator":"and","boost":10,"analyzer":"searchkick_search"}}},{"match":{"_all":{"query":"APPL_US","operator":"and","boost":10,"analyzer":"searchkick_search2"}}},{"match":{"_all":{"query":"APPL_US","operator":"and","boost":1,"analyzer":"searchkick_search","fuzziness":1,"prefix_length":0,"max_expansions":3}}},{"match":{"_all":{"query":"APPL_US","operator":"and","boost":1,"analyzer":"searchkick_search2","fuzziness":1,"prefix_length":0,"max_expansions":3}}}]}},"size":1,"from":0,"fields":[]}'
=> #<Searchkick::Results:0x0000036f6915a0
@klass=
EquityContract(id: integer, ticker: text, name: string, country: string, currency: string, created_at: datetime, updated_at: datetime),
@options=
{:page=>1,
:per_page=>1,
:padding=>0,
:load=>true,
:includes=>nil,
:json=>false,
:match_suffix=>"analyzed",
:highlighted_fields=>[]},
@response=
{"took"=>99,
"timed_out"=>false,
"_shards"=>{"total"=>5, "successful"=>5, "failed"=>0},
"hits"=>
{"total"=>3,
"max_score"=>0.005845671,
"hits"=>
[{"_index"=>"equity_contracts_development_20160317185615341",
"_type"=>"equity_contract",
"_id"=>"234",
"_score"=>0.005845671}]}}>
这里的主要问题是我希望看到我之前创建的索引结果并查看字段的结果 (name
, ticker
,country
,user_id
,prices
).
当我尝试通过 RESTful API 访问 ElasticSearch 时:
curl http://127.0.0.1:9200/equity_contracts_development/_search\?pretty -d '{"query":{"filtered":{"query":{"match_all":{}},"filter":{"and":[{"not":{"filter":{"missing":{"field":"user_id","existence":true,"null_value":true}}}}]}}},"size":100,"from":0,"fields":[]}'
我得到这样的结果:
{
"took" : 54,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 207,
"max_score" : 1.0,
"hits" : [ {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "64",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "83",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "90",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "127",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "139",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "590",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "608",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "622",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "658",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "665",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "672",
"_score" : 1.0
}]
}
}
如何查看关联映射对象的结果,如 prices
中所示?目前 equity.results
returns activerecord 对象数组 EquityContract
而不是索引属性。
我想要 return 在 EquityContract#search_data
中指定的属性并尝试了 equity.response['hits']['hits']
位它不包括所需的属性。有任何想法吗?
看来我必须将 load: false
添加到 #search
,例如:
equity = EquityContract.search "APPL_US", limit: 1, load: false
然后我会得到 _source
包含属性的响应。您可以将 source=true
添加到 HTTP 请求,您应该会在响应中获得完整的属性。
我有 equity_contracts
table 其中有一个 user_contract
和许多 prices
。 EquityContract
模型看起来像:
class EquityContract < ActiveRecord::Base
validates_presence_of :ticker, :name, :country, :currency
has_one :user_contract, as: :contract
has_many :prices
searchkick
scope :search_import, -> { includes(:user_contract, :prices) }
def search_data
{
name: name,
ticker: ticker,
country: country,
user_id: user_contract.try(:user_id),
prices: prices.map do |price|
{
traded_on: price.traded_on.to_s,
close: price.close
}
end
}
end
end
UserContract
看起来像:
class UserContract < ActiveRecord::Base
belongs_to :user
belongs_to :contract, polymorphic: true
end
现在我想索引 EquityContract
中的键 (name
, ticker
,country
,user_id
,prices
) 所以我运行EquityContract.reindex
。
现在,当我尝试做类似 equity = EquityContract.search "APPL_US"
的事情时,我得到 Searchkick::Results
看起来像这样的对象:
[24] pry(main)> equity = EquityContract.search "APPL_US", limit: 1
ETHON: performed EASY effective_url=http://127.0.0.1:9200/equity_contracts_development/_search response_code=200 return_code=ok total_time=0.101687
EquityContract Search (109.5ms) curl http://127.0.0.1:9200/equity_contracts_development/_search?pretty -d '{"query":{"dis_max":{"queries":[{"match":{"_all":{"query":"APPL_US","operator":"and","boost":10,"analyzer":"searchkick_search"}}},{"match":{"_all":{"query":"APPL_US","operator":"and","boost":10,"analyzer":"searchkick_search2"}}},{"match":{"_all":{"query":"APPL_US","operator":"and","boost":1,"analyzer":"searchkick_search","fuzziness":1,"prefix_length":0,"max_expansions":3}}},{"match":{"_all":{"query":"APPL_US","operator":"and","boost":1,"analyzer":"searchkick_search2","fuzziness":1,"prefix_length":0,"max_expansions":3}}}]}},"size":1,"from":0,"fields":[]}'
=> #<Searchkick::Results:0x0000036f6915a0
@klass=
EquityContract(id: integer, ticker: text, name: string, country: string, currency: string, created_at: datetime, updated_at: datetime),
@options=
{:page=>1,
:per_page=>1,
:padding=>0,
:load=>true,
:includes=>nil,
:json=>false,
:match_suffix=>"analyzed",
:highlighted_fields=>[]},
@response=
{"took"=>99,
"timed_out"=>false,
"_shards"=>{"total"=>5, "successful"=>5, "failed"=>0},
"hits"=>
{"total"=>3,
"max_score"=>0.005845671,
"hits"=>
[{"_index"=>"equity_contracts_development_20160317185615341",
"_type"=>"equity_contract",
"_id"=>"234",
"_score"=>0.005845671}]}}>
这里的主要问题是我希望看到我之前创建的索引结果并查看字段的结果 (name
, ticker
,country
,user_id
,prices
).
当我尝试通过 RESTful API 访问 ElasticSearch 时:
curl http://127.0.0.1:9200/equity_contracts_development/_search\?pretty -d '{"query":{"filtered":{"query":{"match_all":{}},"filter":{"and":[{"not":{"filter":{"missing":{"field":"user_id","existence":true,"null_value":true}}}}]}}},"size":100,"from":0,"fields":[]}'
我得到这样的结果:
{
"took" : 54,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 207,
"max_score" : 1.0,
"hits" : [ {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "64",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "83",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "90",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "127",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "139",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "590",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "608",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "622",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "658",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "665",
"_score" : 1.0
}, {
"_index" : "equity_contracts_development_20160317185615341",
"_type" : "equity_contract",
"_id" : "672",
"_score" : 1.0
}]
}
}
如何查看关联映射对象的结果,如 prices
中所示?目前 equity.results
returns activerecord 对象数组 EquityContract
而不是索引属性。
我想要 return 在 EquityContract#search_data
中指定的属性并尝试了 equity.response['hits']['hits']
位它不包括所需的属性。有任何想法吗?
看来我必须将 load: false
添加到 #search
,例如:
equity = EquityContract.search "APPL_US", limit: 1, load: false
然后我会得到 _source
包含属性的响应。您可以将 source=true
添加到 HTTP 请求,您应该会在响应中获得完整的属性。