首页 文章

我可以在CakePHP 3线程查询中对不同于父项的子项进行排序吗?

提问于
浏览
0

我对线程评论有疑问 . 是否可以从此查询(或表级)订购注释DESC和子注释ASC,还是应该进行后查询修改?

您可以在下面找到我的查询,命令所有DESC .


```java
$comments = $this->Comments
            ->find('threaded', ['order' => ['Comments.created' => 'DESC']])
            ->contain(['Users'])
            ->matching(
                'BoardItems',
                function ($q) use ($boardItemId) {
                    return $q->where(
                        [
                            'BoardItems.id' => $boardItemId
                        ]
                    );
                }
            )
            ->all();

1 回答

  • 1

    在SQL级别上

    您应该能够应用 MySql: ORDER BY parent and child 中建议的解决方案

    • 使用 COALESCE 对父母进行分组/排序

    • 通过测试非 NULL 父ID来对子项进行分组

    • 对分组的子项进行排序

    在你的情况下,你按 created 而不是 id 排序,即类似的东西

    ORDER BY 
        COALESCE(Comments.parent_id, Comments.created) DESC, 
        Comments.parent_id IS NOT NULL, 
        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();
    

    也可以看看

    • Cookbook > Database Access & ORM > Query Builder > Selecting Data

    • Cookbook > Database Access & ORM > Query Builder > Using SQL Functions

    • Cookbook > Database Access & ORM > Query Builder > Advanced Conditions

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

    这将检索所有降序排序,然后按 created 字段对所有 children 数组进行排序 . 类似地,您可以在视图中输出/使用它们之前对事物进行排序,具体取决于您计划对结果做些什么 .

    如果你想保留表中的内容,你可以将它全部包装在自定义查找程序中和/或通过表类上的方法检索排序闭包 .

    也可以看看

    • Cookbook > Collections > Sorting

    • Cookbook > Collections > Iterating

相关问题