如何制作通用函数以将嵌套对象减少为 CSV 样式数组?



我正在尝试弄清楚如何将嵌套数组/树展平为CSV样式格式。

我有一个来自 elasticsearch 的结果,如下所示(注意 - 每个"存储桶"属性可以有多个或 0 个项目(:

$data = array(
'reeta.datetime_day' => array(
'buckets' => array(
0 => array(
'key_as_string' => '2018-07-27T00:00:00.000Z',
'key' => 1532649600000,
'doc_count' => 4,
'ticket.employee_name' => array(
'doc_count_error_upper_bound' => 0,
'sum_other_doc_count' => 0,
'buckets' => array(
0 => array(
'key' => 'Era Swift',
'doc_count' => 3,
'ticket.order_type' => array(
'doc_count_error_upper_bound' => 0,
'sum_other_doc_count' => 0,
'buckets' => array(
0 => array(
'key' => 'Dine In',
'doc_count' => 3,
'ticket.total_guest_count' => array(
'value' => 17,
) ,
'ticket.total_revenue' => array(
'value' => 273,
) ,
) ,
) ,
) ,
) ,
1 => array(
'key' => 'Dorothea Friesen',
'doc_count' => 1,
'ticket.order_type' => array(
'doc_count_error_upper_bound' => 0,
'sum_other_doc_count' => 0,
'buckets' => array(
0 => array(
'key' => 'Take Out',
'doc_count' => 1,
'ticket.total_guest_count' => array(
'value' => 2,
) ,
'ticket.total_revenue' => array(
'value' => 195,
) ,
) ,
) ,
) ,
) ,
) ,
) ,
)
)
)

(;

我有一个用于获取这些聚合的维度和指标列表,这些维度和指标各不相同,例如,对于上述结果,使用以下方法:

$dimensions = ['reeta.datetime_day', 'ticket.employee_name', 'ticket.order_type'];
$metrics = ['ticket.total_guest_count', 'ticket.total_revenue'];

我希望是这样的:

$result = [
// the first bucket of the deepest dimension (ticket.order_type)
[
1532649600000, // the first dimensions key value
'Era Swift', // the second dimensions key value
'Dine In', // the thirs dimensions key value
17, // the first metrics value
273 // the second metrics value
],
// the second bucket of the deepest dimension (ticket.order_type)
[
1532649600000, // the first dimensions key value
'Dorothea Friesen', // the second dimensions key value
'Take Out', // the thirs dimensions key value
2, // the first metrics value
195 // the second metrics value
],
];

为了更好地解释我的用例,我创建了一个 API,它接受许多维度和指标,然后查询 ES 以获得结果。然后,我获取这些结果并使用它们为Google图表(https://developers.google.com/chart/interactive/docs/datatables_dataviews(创建数据表。

我尝试编写许多递归函数,array_walk_recursive等,并尝试在谷歌上搜索任何类似的例子,但在任何地方都找不到。

我尝试浏览并检查:

$array[$dimension]['buckets']

要知道当索引不存在与动态访问多维数组值一起存在时,我处于最深的层次

但我总是得到不正确的结果。我只是不能简单地展平数组,因为我需要为每个最深级别的存储桶提供一个数组项目。

希望这是有道理的,但我很乐意澄清并在这里有一个更大的数据集: https://pastebin.com/mU2xkQGB

如果有人能指出我正确的方向或任何远程相似的例子,将不胜感激,我确实有一堆嵌套的 foreach 块在某个时候工作,但一旦我改变尺寸,它当然不起作用。

我确实设法找到了一个解决方案,它绝对不是最好的,但它通常适用于任何数量的维度和指标。

本质上,我使用 https://github.com/nicmart/Tree 构建了一个树对象,因此可以遍历节点,因此每次我添加指标时,我都可以遍历回它的父级并为它创建一个表行。

请参阅下面的工作代码:

composer require nicmart/tree

这是文件

<?php
require 'vendor/autoload.php';
$array = json_decode('{"reeta.datetime_day":{"buckets":[{"key_as_string":"2018-07-27T00:00:00.000Z","key":1532649600000,"doc_count":4,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":3,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":3,"ticket.total_guest_count":{"value":17},"ticket.total_revenue":{"value":273}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":195}}]}}]}},{"key_as_string":"2018-07-28T00:00:00.000Z","key":1532736000000,"doc_count":6,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":3,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":2,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":212}},{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":112}}]}},{"key":"Dorothea Friesen","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":2,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":379.97999572753906}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":226.35000610351562}}]}}]}},{"key_as_string":"2018-07-29T00:00:00.000Z","key":1532822400000,"doc_count":0,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[]}},{"key_as_string":"2018-07-30T00:00:00.000Z","key":1532908800000,"doc_count":2,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":3},"ticket.total_revenue":{"value":105.3499984741211}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":1},"ticket.total_revenue":{"value":160.35000610351562}}]}}]}},{"key_as_string":"2018-07-31T00:00:00.000Z","key":1532995200000,"doc_count":2,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":2,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":234}}]}}]}},{"key_as_string":"2018-08-01T00:00:00.000Z","key":1533081600000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":151.35000610351562}}]}}]}},{"key_as_string":"2018-08-02T00:00:00.000Z","key":1533168000000,"doc_count":5,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":5}},{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":140}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":241}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":3},"ticket.total_revenue":{"value":157}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":4},"ticket.total_revenue":{"value":240}}]}}]}},{"key_as_string":"2018-08-03T00:00:00.000Z","key":1533254400000,"doc_count":3,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":2,"ticket.total_guest_count":{"value":12},"ticket.total_revenue":{"value":169}}]}},{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":3},"ticket.total_revenue":{"value":260.3500061035156}}]}}]}},{"key_as_string":"2018-08-04T00:00:00.000Z","key":1533340800000,"doc_count":3,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Foster Bashirian","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":2,"ticket.total_guest_count":{"value":16},"ticket.total_revenue":{"value":277}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":118}}]}}]}},{"key_as_string":"2018-08-05T00:00:00.000Z","key":1533427200000,"doc_count":3,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":68}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":274}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":5},"ticket.total_revenue":{"value":180}}]}}]}},{"key_as_string":"2018-08-06T00:00:00.000Z","key":1533513600000,"doc_count":4,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":172}}]}},{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":119}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":4},"ticket.total_revenue":{"value":120}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":37}}]}}]}},{"key_as_string":"2018-08-07T00:00:00.000Z","key":1533600000000,"doc_count":2,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":134}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":4},"ticket.total_revenue":{"value":71}}]}}]}},{"key_as_string":"2018-08-08T00:00:00.000Z","key":1533686400000,"doc_count":2,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":252}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":244.35000610351562}}]}}]}},{"key_as_string":"2018-08-09T00:00:00.000Z","key":1533772800000,"doc_count":3,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":246}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":23}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":34}}]}}]}},{"key_as_string":"2018-08-10T00:00:00.000Z","key":1533859200000,"doc_count":4,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":77.3499984741211}}]}},{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":195}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":85}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":161}}]}}]}},{"key_as_string":"2018-08-11T00:00:00.000Z","key":1533945600000,"doc_count":3,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":2},"ticket.total_revenue":{"value":38}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":5},"ticket.total_revenue":{"value":25}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":5},"ticket.total_revenue":{"value":100}}]}}]}},{"key_as_string":"2018-08-12T00:00:00.000Z","key":1534032000000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":1},"ticket.total_revenue":{"value":201}}]}}]}},{"key_as_string":"2018-08-13T00:00:00.000Z","key":1534118400000,"doc_count":4,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dorothea Friesen","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":2,"ticket.total_guest_count":{"value":15},"ticket.total_revenue":{"value":183.3499984741211}}]}},{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":116}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":5},"ticket.total_revenue":{"value":117}}]}}]}},{"key_as_string":"2018-08-14T00:00:00.000Z","key":1534204800000,"doc_count":4,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":2,"ticket.total_guest_count":{"value":11},"ticket.total_revenue":{"value":255}}]}},{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":3},"ticket.total_revenue":{"value":73.3499984741211}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":7}}]}}]}},{"key_as_string":"2018-08-15T00:00:00.000Z","key":1534291200000,"doc_count":2,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":101}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":10},"ticket.total_revenue":{"value":31}}]}}]}},{"key_as_string":"2018-08-16T00:00:00.000Z","key":1534377600000,"doc_count":0,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[]}},{"key_as_string":"2018-08-17T00:00:00.000Z","key":1534464000000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":4},"ticket.total_revenue":{"value":155}}]}}]}},{"key_as_string":"2018-08-18T00:00:00.000Z","key":1534550400000,"doc_count":2,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":130.35000610351562}}]}},{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":5},"ticket.total_revenue":{"value":255.97999572753906}}]}}]}},{"key_as_string":"2018-08-19T00:00:00.000Z","key":1534636800000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":4},"ticket.total_revenue":{"value":176}}]}}]}},{"key_as_string":"2018-08-20T00:00:00.000Z","key":1534723200000,"doc_count":3,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":290.3500061035156}},{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":88}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":1},"ticket.total_revenue":{"value":88}}]}}]}},{"key_as_string":"2018-08-21T00:00:00.000Z","key":1534809600000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":64}}]}}]}},{"key_as_string":"2018-08-22T00:00:00.000Z","key":1534896000000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":171.35000610351562}}]}}]}},{"key_as_string":"2018-08-23T00:00:00.000Z","key":1534982400000,"doc_count":5,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Delbert Abernathy","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":2,"ticket.total_guest_count":{"value":11},"ticket.total_revenue":{"value":112}}]}},{"key":"Conor Gerlach","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":6},"ticket.total_revenue":{"value":120}}]}},{"key":"Dorothea Friesen","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":73.3499984741211}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":1},"ticket.total_revenue":{"value":149}}]}}]}},{"key_as_string":"2018-08-24T00:00:00.000Z","key":1535068800000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":10},"ticket.total_revenue":{"value":56}}]}}]}},{"key_as_string":"2018-08-25T00:00:00.000Z","key":1535155200000,"doc_count":6,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Conor Gerlach","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":2,"ticket.total_guest_count":{"value":14},"ticket.total_revenue":{"value":228.35000038146973}}]}},{"key":"Era Swift","doc_count":2,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":8},"ticket.total_revenue":{"value":27}},{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":9},"ticket.total_revenue":{"value":154}}]}},{"key":"Delbert Abernathy","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":5},"ticket.total_revenue":{"value":114}}]}},{"key":"Foster Bashirian","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Take Out","doc_count":1,"ticket.total_guest_count":{"value":3},"ticket.total_revenue":{"value":13.350000381469727}}]}}]}},{"key_as_string":"2018-08-26T00:00:00.000Z","key":1535241600000,"doc_count":1,"ticket.employee_name":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Era Swift","doc_count":1,"ticket.order_type":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Dine In","doc_count":1,"ticket.total_guest_count":{"value":4},"ticket.total_revenue":{"value":244}}]}}]}}]}}', true);
$dimensions = ['reeta.datetime_day', 'ticket.employee_name', 'ticket.order_type'];
$metrics = ['ticket.total_guest_count', 'ticket.total_revenue'];
use TreeNodeNode;
class TableFormatter
{
public static function formatDataTable($aggregationResults, array $dimensions, array $metrics) {
// initialize main data to return
$data = [];
$headerRow = [];
// now put in each metric we have
foreach($dimensions as $dimension) {
array_push($headerRow, $dimension);
}
// now put in each metric we have
foreach($metrics as $metric) {
array_push($headerRow, $metric);
}
$data[] = $headerRow;
$aggs = self::convertToTree($aggregationResults, $dimensions, $metrics);
return array_merge($data, $aggs);
}
private static function convertToTree(array $aggregationResults, array $dimensions, array $metrics, $tree = null, & $data = []) {
// initialize a tree if there isn't one already
if (!$tree) {
$tree = new Node('root');
}
// if there are dimensions then continue
if (!empty($dimensions)) {
// get the next dimension
$dimension = array_shift($dimensions);
// ensure the data is set for that dimension
if (isset($aggregationResults[$dimension]['buckets'])) {

// loop through each buckt
foreach ($aggregationResults[$dimension]['buckets'] as $bucket) {
// make child node to store the value and add to the parent node
$dimensionValue = new Node($bucket['key']);
$tree->addChild($dimensionValue);
// recursively call function to traverse through each bucket
self::convertToTree($bucket, $dimensions, $metrics, $dimensionValue, $data);
}
} else {
throw new Exception("No aggregation data for [".$dimension."]", Error::ERROR_INTERNAL_ERROR);
}
} else {
self::formatMetricData($aggregationResults, $metrics, $tree, $data);
}
return $data;
}
private static function formatMetricData(array $bucket, array $metrics, $tree, & $data) {
if(empty($bucket)) {
return $tree;
}
// setup the array for the table row
$item = [];
// now add each metric
foreach($metrics as $metric) {
$metricValue = new Node($bucket[$metric]['value']);
// add in the metrics
$item[] = $metricValue->getValue();
$tree->addChild($metricValue);
}
// metrics are the wrong way round at this point so reverse them
$item = array_reverse($item);
// add in the key
$item[] = $bucket['key'];
// now we can traverse the tree all the way up and get the parents
$node = $tree->getParent();
while ($node->getValue() != 'root') {
$item[] = $node->getValue();
$node = $node->getParent();
}
// reverse here as it's in the wrong order
$data[] = array_reverse($item);
return $tree;
}
}
$result = TableFormatter::formatDataTable($array, $dimensions, $metrics);
var_dump($result);

如前所述,绝对不是迄今为止最有效的解决方案,但它有效并花费大量时间四处寻找类似的东西,因此希望这可以帮助解锁某人,直到出现更好的解决方案。

谢谢!

最新更新