Elasticsearch结果到表

时间:2014-08-06 16:28:01

标签: ruby-on-rails ruby json elasticsearch

我正在使用gem elasticsearch-rails以动态方式从elasticsearch检索数据,这意味着根据用户的选择,结果可以没有或多个聚合。

想象一下这样的反应:

(...)
"aggregations"=>
{"agg_insignia_id"=>
  {"buckets"=>
    [{"key"=>1,
      "key_as_string"=>"1",
      "doc_count"=>32156,
      "agg_chain_id"=>
       {"buckets"=>
         [{"key"=>9,
           "key_as_string"=>"9",
           "doc_count"=>23079,
           "agg_store_id"=>
            {"buckets"=>
              [{"key"=>450,
                "key_as_string"=>"450",
                "doc_count"=>145,
                "agg_value"=>{"value"=>1785.13}},

               {"key"=>349,
                "key_as_string"=>"349",
                "doc_count"=>143,
                "agg_value"=>{"value"=>1690.37}},

如何在表格数据中转换数据?像

|  insignia_id  |  chain_id  |  store_id  |  value   |
|  1            |  9         |  450       |  1785.13 |
|  1            |  9         |  349       |  1690.37 |
(...)

编辑::清楚我正在寻找的响应,这里有两个选择:数组(简单)或哈希数组。

数组样式: [[insignia_id, chain_id, store_id, value], [1,9,450,1785.13], [1,9,349,1690.37],...]

哈希样式数组: [{insignia_id => 1, chain_id => 9, store_id => 450, value => 1785.13}, {insignia_id => 1, chain_id => 9, store_id => 450, value => 1690.37 }]

后者更像是一种活跃的记录风格......

1 个答案:

答案 0 :(得分:2)

好的,所以我想出了一个阵列响应的解决方案。

首先为未来的事情添加了一个帮助......

class Hash
  def deep_find(key, object=self, found=nil)
    if object.respond_to?(:key?) && object.key?(key)
      return object[key]
    elsif object.is_a? Enumerable
      object.find { |*a| found = deep_find(key, a.last) }
      return found
    end
  end
end

现在用于阵列算法(在关注中添加):

def self.to_table_array(data, aggs, final_table = nil, row = [])
    final_table = [aggs.keys] if final_table.nil?
    hash_tree = data.deep_find(aggs.keys.first)

    if aggs.values.uniq.length == 1 && aggs.values.uniq == [:data]
        aggs.keys.each do |agg|
            row << data[agg]["value"]
        end
        final_table << row
    else
        hash_tree["buckets"].each_with_index do |h, index|
            row.pop if index > 0
            aggs.shift if index == 0

            row << h["key_as_string"]
            final_table = to_table_array(h, aggs.clone, final_table, row.clone)
        end
    end

    final_table
end

可以这样调用此方法:

#_fields = { "insignia_id" => :row, "chain_id" => :row, "store_id"=> :row, "value" => : data }
#res.response => Elasticsearch response
result = to_table_array(res.response, _fields)

对于这种情况,有一些非常具体的事情,就像你可以在这个_fields变量上看到的那样。我还假设每个聚合都有术语本身的名称。对于每种可能的情况,其余部分完全相同。

从这里只需更换几行就可以得到哈希数组的结果。

我在这里放了很多efford。希望这能帮助除我之外的其他人。