【问题标题】:How to handle nested documents with Searchkick and Rails?如何使用 Searchkick 和 Rails 处理嵌套文档?
【发布时间】:2016-03-17 18:35:20
【问题描述】:

我有equity_contracts 表,其中有一个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 中的键(nametickercountryuser_idprices)所以我运行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}]}}>

这里的主要问题是我希望看到我之前所做的索引结果并查看字段结果(nametickercountryuser_idprices)。

当我尝试通过 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 返回活动记录对象EquityContract 的数组,而不是索引属性。

我想返回EquityContract#search_data 中指定的属性并尝试了equity.response['hits']['hits'] 位,它不包含所需的属性。有任何想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 elasticsearch searchkick


    【解决方案1】:

    看来我必须将load: false 添加到#search 类似:

    equity = EquityContract.search "APPL_US", limit: 1, load: false
    

    然后我会得到_source 的响应,其中包含属性。您可以将 source=true 添加到 HTTP 请求中,并且您应该获得包含响应的完整属性。

    【讨论】:

      猜你喜欢
      • 2022-07-24
      • 2014-05-11
      • 2017-11-13
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-02
      • 2014-05-07
      相关资源
      最近更新 更多