如何使用 Searchkick 和 Rails 处理嵌套文档?

How to handle nested documents with Searchkick and Rails?

我有 equity_contracts table 其中有一个 user_contract 和许多 pricesEquityContract 模型看起来像:

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 请求,您应该会在响应中获得完整的属性。