我在CakePHP中有一个查询,它返回以下结构中的数据对象:
[
{
"join_id": 1,
"contract_id": 1,
"title": "Title",
"sales": 500,
"earnings": 50,
"publisher": "Publisher",
"end_date": "2016-11-15"
},
{
"join_id": 2,
"contract_id": 1,
"title": "Title",
"sales": 500,
"earnings": 50,
"publisher": "Publisher",
"end_date": "2016-01-15"
},
{
"join_id": 3,
"contract_id": 2,
"title": "Title",
"sales": 500,
"earnings": 50,
"publisher": "Publisher",
"end_date": "2016-05-15"
}
]
我想要做的是更改结构,使其被contract_id
拆分,并计算与其子项相关的某些字段,如下所示:
[
{
"contract_id": 1,
"end_date": "2016-11-15",
"joins": [
{
"join_id": 1,
"title": "Title",
"sales": 500,
"earnings": 50,
"publisher": "Publisher",
"end_date": "2016-11-15"
},
{
"join_id": 2,
"title": "Title",
"sales": 500,
"earnings": 50,
"publisher": "Publisher",
"end_date": "2016-01-15"
}
]
},
{
"contract_id": 2,
"end_date": "2016-05-15",
"joins": [
{
"join_id": 3,
"title": "Title",
"sales": 500,
"earnings": 50,
"publisher": "Publisher",
"end_date": "2016-11-15"
}
]
}
]
总之,我希望按contract_id
对结果进行分组,并计算其所有孩子的最新end_date
。
我已经能够使用mapReduce来获得按contract_id
分组的结果,如下所示:
$mapper = function ($contractstitle, $key, $mapReduce) {
$contract_id = $contractstitle->contract_id;
$mapReduce->emitIntermediate($contractstitle, $contract_id);
};
$reducer = function ($contractstitle, $contract_id, $mapReduce) {
$mapReduce->emit($contractstitle, $contract_id);
};
$query->mapReduce($mapper, $reducer);
但我无法弄清楚如何为其添加计算字段。我对mapReduce不太熟悉 - 我想我需要遍历数据以获得最大值,但我不知道如何去做。
我还看过formatResults
方法,但我不确定这是否是我应该使用的方法。
谢谢,
KEZ
编辑 - 请求的信息:
我在初始问题中简化了结果结构,因为我花了很多时间尝试构建一个不会无缘无故地多次循环的查询。在Contracts中启动查询并包含ContractsTitles会很好,但ORM似乎不喜欢这样,所以在我看来,我最好的选择是在我获得所需的所有信息后重构结果。显然,我可以手动迭代结果并构建我想要的数组,但我觉得必须有更好的方法来做到这一点。
这是正在使用的表的基本结构:
ContractsTitles hasOne Reversions
ContractsTitles hasOne Publications
ContractsTitles belongsTo Contracts
ContractsTitles belongsTo Titles
ContractsTitles hasMany Royalties
这是查询模型中的代码:
$subQuery = $this->Contracts->Royalties
->find()
->contain(['Contracts'])
->where(['Contracts.publisher_id' => $options['publisher_id']]);
$subQuery
->select(['contract_id' => 'Royalties.contract_id','title_id' => 'Royalties.title_id','sold' => $subQuery->func()->sum("sold"), 'earned' => $subQuery->func()->sum("earned")])
->group(['Royalties.title_id','Royalties.contract_id']);
$query = $this->Contracts->ContractsTitles
->find()
->select(['Contracts.id', 'Contracts.date', 'Titles.title', 'Reversions.date', 'Publications.date', 'sold' => 'r.sold', 'earned' => 'r.earned'])
->where(['Contracts.publisher_id' => $options['publisher_id']])
->contain(['Contracts','Titles','Reversions','Publications'])
->join([
'table' => $subQuery,
'alias' => 'r',
'type' => 'LEFT',
'conditions' => ['r.contract_id = ContractsTitles.contract_id','r.title_id = ContractsTitles.title_id']
])
->order(['Contracts.date DESC, Publications.date DESC']);
答案 0 :(得分:0)
您可以在查询后尝试使用->toArray()
。
我听说不是很好用,但可能是你想要的解决方案。
以下是我所指的一些信息: http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#finding-key-value-pairs