Я пытаюсь понять, как я могу сгладить вложенный массив / дерево в формат стиля CSV.

У меня есть результат elasticsearch, который выглядит следующим образом (обратите внимание - каждое свойство buckets может иметь несколько или 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 и т. Д. И пробовал поискать в Google любой подобный пример, но нигде не нашел.

Я попытался пройтись и проверить:

$array[$dimension]['buckets']

Чтобы знать, что я был на самом глубоком уровне, когда индекс не существовал в сочетании с с динамическим доступом к многомерному массиву значение

Но я всегда получаю неверные результаты. Я просто не могу просто сгладить массив, так как мне нужен элемент массива для каждого сегмента самого глубокого уровня.

Надеюсь, в этом есть какой-то смысл, но я буду рад уточнить и разместить здесь более крупный набор данных: https://pastebin.com/mU2xkQGB

Если бы кто-нибудь мог указать мне в правильном направлении или какие-либо примеры чего-то отдаленно похожего, что было бы очень полезно, у меня действительно была куча вложенных блоков foreach, работающих в какой-то момент, но как только я изменил размер размеров, конечно, это было не так. за работой.

0
Tom_Corbett 11 Сен 2018 в 06:21

1 ответ

Лучший ответ

Мне удалось найти одно решение, оно определенно не лучшее, но в целом работает для любого количества параметров и показателей.

По сути, я построил древовидный объект, используя 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 Tree\Node\Node;

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);

Как уже говорилось, определенно не самое эффективное решение, но оно работает и потратило много времени на поиск чего-то похожего, поэтому, надеюсь, это поможет разблокировать кого-то, пока не появится лучшее решение.

Благодарность!

0
Tom_Corbett 11 Сен 2018 в 17:43