Elasticsearch结果到表 [英] Elasticsearch result to table

查看:48
本文介绍了Elasticsearch结果到表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用宝石 elasticsearch-rails 以动态方式从elasticsearch检索数据,意味着根据用户的选择,结果可以不包含一个或多个聚合.

I am using the gem elasticsearch-rails to retrieve data from elasticsearch in a dynamic way, meaning that the result can have none or multiple aggregations depending on users choices.

想象这样的响应:

(...)
"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}},

如何将这些数据转换为表格数据?喜欢

How can I transform that data in a tabular data? like

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

:清楚我要寻找的响应,这里有两个选择:数组(简单)或哈希数组.

EDIT :: Being clear on the response I am looking for, two choices here: Array (simple) or Array of hashes.

数组样式: [[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,值=>1785.13},{insignia_id =>1,chain_id =>9,store_id =>450,值=>1690.37}]

后面的内容更像是一个主动录制的样式...

The later is more like an activerecord style...

推荐答案

好的,所以我想出了一个用于数组响应的解决方案.

ok, so I came up with a solution for an array response.

首先为即将发生的事情添加了一个助手...

Firstly added a helper for what comes ahead...

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

现在介绍数组算法(需要注意的是):

now for the array algorithm (added in a concern):

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

对此方法的调用可以这样进行:

The call for this method could be made like this:

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

有些特殊情况,例如您可以在此 _fields 变量中看到.另外,我假设每个聚合都具有术语本身的名称.对于每种可能的情况,其余部分都是相同的.

There are some things quite specific to this case like you can see on this _fields variable. Also I'm assuming each aggregation has the name of the term itself. The rest is quite the same for every possible case.

从这里开始,只需替换几行即可很简单地得到哈希数组的结果.

A result of an array of hashes is pretty simple from here just by replacing few lines.

我在这上面放了很多东西.希望这对我以外的人有帮助.

I put a lot of efford in this. Hope this helps someone else other than me.

这篇关于Elasticsearch结果到表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆