我可以在CakePHP 3线程查询中对不同于父级的子级进行排序吗?
我有一个关于线程评论的问题。是否可以从此查询(或表级别)中排序注释DESC和子注释ASC,或者是否应该在查询修改后进行排序 在下面,您可以找到我的查询,该查询将所有订单都订购到DESC ``` ```在SQL级别 您应该能够应用中建议的解决方案我可以在CakePHP 3线程查询中对不同于父级的子级进行排序吗?,cakephp,tree,cakephp-3.0,cakephp-3.x,Cakephp,Tree,Cakephp 3.0,Cakephp 3.x,我有一个关于线程评论的问题。是否可以从此查询(或表级别)中排序注释DESC和子注释ASC,或者是否应该在查询修改后进行排序 在下面,您可以找到我的查询,该查询将所有订单都订购到DESC ``` ```在SQL级别 您应该能够应用中建议的解决方案 使用合并首先对父级进行分组/排序 通过测试非父ID对子项进行分组 对分组的子项进行排序 在您的情况下,您将按创建的而不是id进行排序,例如 orderby 合并(Comments.parent_id,Comments.created)描述, Commen
合并
首先对父级进行分组/排序创建的而不是id
进行排序,例如
orderby
合并(Comments.parent_id,Comments.created)描述,
Comments.parent_id不为空,
Comments.created ASC
要以适当的查询生成器方式构建此函数,必须使用order()
和orderDesc()
方法,以便可以使用查询表达式,类似于
$query = $this->Comments
->find('threaded');
$comments = $query
// ->contain(...)
// ->matching(...)
// COALESCE(Comments.parent_id, Comments.created) DESC
->orderDesc($query->func()->coalesce([
'Comments.parent_id' => 'identifier',
'Comments.created' => 'identifier'
]))
// Comments.parent_id IS NOT NULL
->order($query->newExpr()->isNotNull('Comments.parent_id'))
// Comments.created ASC
->order(['Comments.created' => 'ASC'])
->all();
另见
在PHP级别上
事后排序也是一种选择,例如使用递归结果格式化程序:
$sortChildren = function($row) use (&$sortChildren) {
if (!empty($row['children'])) {
$row['children'] =
collection($row['children'])
->sortBy('created', SORT_ASC)
->map($sortChildren)
->toArray();
}
return $row;
};
$comments = $this->Comments
->find('threaded')
// ->contain(...)
// ->matching(...)
->order(['Comments.created' => 'DESC'])
->formatResults(function ($results) use ($sortChildren) {
return $results->map($sortChildren);
})
->all();
这将按降序检索所有内容,然后按创建的字段对所有子数组进行升序排序。类似地,您可以在视图中输出/使用内容之前对其进行排序,具体取决于您计划对结果执行的操作
如果您想在表中保留内容,例如,您可以将这些内容打包到自定义查找器中,并/或通过表类上的方法检索排序闭包
另见
谢谢您的详细回答,我可以在周一尝试,但从外观上看,两者都可以解决我的问题。我曾考虑过使用第二个类似的方法,使用集合,但mysql解决方案似乎更好。现在终于尝试了mysql解决方案,效果很好,再次感谢
$sortChildren = function($row) use (&$sortChildren) {
if (!empty($row['children'])) {
$row['children'] =
collection($row['children'])
->sortBy('created', SORT_ASC)
->map($sortChildren)
->toArray();
}
return $row;
};
$comments = $this->Comments
->find('threaded')
// ->contain(...)
// ->matching(...)
->order(['Comments.created' => 'DESC'])
->formatResults(function ($results) use ($sortChildren) {
return $results->map($sortChildren);
})
->all();