编程语言
首页 > 编程语言> > CakePHP 3:更改结果集的结构

CakePHP 3:更改结果集的结构

作者:互联网

我是CakePHP的新手,有以下问题:

我有“图像”,“关键字”和“KeywordCategories”表.每个图像都可以有许多关键字(多对多),每个关键字都有一个类别(多对一).使用检索图像列表

$images = $this->Images->find()->contain(['Keywords',  'Keywords.KeywordCategories']);

返回如下结果结构:

[
   {
      "id":1,
      "keywords":[
         {
            "keyword":"Dog",
            "keyword_category":{
               "title":"Animal"
            }
         },
         {
            "keyword":"Cat",
            "keyword_category":{
               "title":"Animal"
            }
         },
         {
            "keyword":"Black",
            "keyword_category":{
               "title":"Color"
            }
         }
      ]
   }
]

这没关系,但我想在这样的结构中按关键字类别对关键字进行分组:

[
   {
      "id":1,
      "keyword_categories":[
         {
            "title":"Animal",
            "keywords":[
               {
                  "keyword":"Dog"
               },
               {
                  "keyword":"Cat"
               }
            ]
         },
         {
            "title":"Color",
            "keywords":[
               {
                  "keyword":"Black"
               }
            ]
         }
      ]
   }
]

知道如何通过CakePHP查询实现这一目标吗?

解决方法:

这种格式几乎是反向包含,仅使用ORMs关联自动魔法是不可能的.您必须单独获取相关数据,过滤它,并将其注入图像结果…您甚至可以创建一个自定义关联类,包含,提取和拼接结果,但如果你问的话,那就太过分了我.

因为你不得不做一些额外的格式化(并且只是为了将结果拼接在一起),我只是简单地使用一些集合格式foo,类似于

// ...
->find()
->contain(['Keywords', 'Keywords.KeywordCategories'])
->formatResults(function ($results) {
    /* @var $results \Cake\Datasource\ResultSetInterface|\Cake\Collection\CollectionInterface */
    return $results->map(
        function ($image) {
            $image['keyword_categories'] =
                collection($image['keywords'])
                    ->groupBy('keyword_category.title')
                    ->map(function ($keywords, $category) {
                        foreach ($keywords as &$keyword) {
                            unset($keyword['keyword_category']);
                        }
                        return [
                            'title' => $category,
                            'keywords' => $keywords
                        ];
                    })
                    ->toList();
            unset($image['keywords']);
            return $image;
        }
    );
});

*用于说明目的的未经测试的示例代码

即在每个图像结果上创建一个名为keyword_categories的计算字段,由包含的关键字组成,按关联的类别标题分组,关键字嵌套在一个数组中,其中包含从关键字中删除类别的标题和关键字字段,最后重新显示 – 将整个事物指数作为基本的数字索引数组.

也可以看看

> Cookbook > Database Access & ORM > Query Builder > Adding Calculated Fields
> Cookbook > Collections > Grouping and Counting > Collection::groupBy()
> Cookbook > Collections > Iterating > Collection::map()
> API > \Cake\Collection\CollectionInterface::toArray()
> API > \Cake\Collection\CollectionInterface::toList()

标签:php,cakephp,cakephp-3-x
来源: https://codeday.me/bug/20190609/1201716.html