【问题标题】:Changing the structure of results object in CakePHP 3在 CakePHP 3 中改变结果对象的结构
【发布时间】:2016-06-29 10:06:55
【问题描述】:

我在 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 方法,但我不确定我是否应该使用它。

谢谢,

凯兹

编辑 - 要求的信息:

我在最初的问题中简化了结果结构,因为我花了很多时间尝试构建一个最终不会无缘无故循环多次的查询。在 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']);

【问题讨论】:

  • 你能提供你的表结构和模型定义吗?
  • 嗨,Haresh,我已经更新了我的问题,但我不确定它会有多大帮助!

标签: cakephp orm cakephp-3.0


【解决方案1】:

您可以尝试在查询后使用->toArray()

我听说这不是很适合使用,但可能是您想要的解决方案。

以下是我所指的一些信息: http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#finding-key-value-pairs

【讨论】:

    猜你喜欢
    • 2016-02-06
    • 2019-12-18
    • 1970-01-01
    • 2023-03-10
    • 2015-06-19
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 2015-02-04
    相关资源
    最近更新 更多