代码之家  ›  专栏  ›  技术社区  ›  sibidiba

CakePHP模型:Containable中的COUNT(*)

  •  11
  • sibidiba  · 技术社区  · 16 年前

    我有一个CakePHP1.3应用程序,非常喜欢它 Containable behavior

    让我们假设我的帖子与评论有一对多的关系。我使用Containable查询(分页)所有帖子和所属评论的列表。但我只对每篇文章有多少评论感兴趣。我没有找到任何方法可以在不获取所有注释行的情况下使用containable实现此查询。我试过:

    $this->paginate=array(
                'fields' => 'Post.title, Post.created',
                'contain' => array('Comment'=>'COUNT(*) AS count'),
            );
    

    “模型”注释中的结果与模型“计数”错误消息不关联。

    $this->paginate=array(
                'fields' => array('Post.title, Post.created'),
                'contain' => array('Comment'=>array('fields'=>'COUNT(*) AS count'),
            );
    

    $this->paginate=array(
                'fields' => 'Post.title, Post.created, COUNT(Comment.id)',
                'contain' => array('Comment'=>array('fields'=>''),
            );
    

    但是这会导致一个错误,因为有许多关系是独立查询的,所以答案表不在Post条目的查询中。 如何计算一篇文章的评论数?

    2 回复  |  直到 16 年前
        1
  •  11
  •   pawelmysior    16 年前

    comment_count posts 表,并将此键添加到注释模型$belongsTo Post数组中:

    'counterCache' => true

    这样更好,因为当您为用户获取数据时,它的速度更快,甚至不需要触摸注释表。由于您使用的是可控制的行为,我想速度和轻量级是您所追求的。

        2
  •  5
  •   SunSparc    14 年前

    我也有同样的问题。PawelmPhysior给出的答案很好,并引出了解决方案。

    我在CakePHP书中找到了更多细节: 3.7.4.1.1 counterCache - Cache your count()

    我有两张桌子:Post和Image。当我将一个图像添加到一篇文章中时,我希望跟踪每篇文章在文章索引列表上显示的图像数量,而不需要在图像表上运行额外的计数查询。

    CREATE TABLE posts
    (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    user_id INTEGER UNSIGNED NOT NULL,
    title VARCHAR(255),
    body TEXT,
    created DATETIME,
    modified DATETIME,
    image_count INTEGER UNSIGNED,
    PRIMARY KEY (id)
    ) ENGINE=InnoDB;
    
    CREATE TABLE images
    (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    post_id INTEGER UNSIGNED NOT NULL,
    filename VARCHAR(255),
    created DATETIME,
    modified DATETIME,
    PRIMARY KEY (id)
    ) ENGINE=InnoDB;
    

    image_count posts 桌子没有什么特别的需要 images 桌子

    class Post extends AppModel
    {
        var $name = 'Memory';
        var $hasMany = array(
            'Image' => array(
                'className' => 'Image',
                'foreignKey' => 'post_id',
                'dependent' => false
            )
        );
    }
    
    class Image extends AppModel
    {
        var $name = 'Image';
        var $belongsTo = array(
            'Post' => array(
                'className' => 'Post',
                'foreignKey' => 'post_id',
                'counterCache' => true
            )
        );
    }
    

    注意 counterCache 已添加到 Image Post 模型

    $this->Post->Behaviors->attach('Containable');
    $post = $this->Post->find('all', array(
        'conditions' => array('user_id' => 7),
        'order' => array('Post.created DESC'),
        'contain' => array(
            'Post' => array(
                'User' => array('first_name', 'last_name')
            )
        )
    ));
    

    现在当我们做一个 find 无需执行任何特殊操作来查找计数,因为它自动成为 邮递 图像计数

    Array
    (
    [Post] => Array
            (
                [0] => Array
                    (
                        [id] => 14
                        [user_id] => 7
                        [title] => Another great post
                        [body] => Lorem ipsum...
                        [created] => 2011-10-26 11:45:05
                        [modified] => 2011-10-26 11:45:05
                        [image_count] => 21
                        [User] => Array
                        (
                            [first_name] => John
                            [last_name] => Doe
                        )
                    )
            )
    )
    

    需要注意的一点是,如果将counterCache添加到现有数据库结构中,则 在另一个之前将为零 形象 增加了。此时,CakePHP将进行实际计数并更新 达到正确的数量。

    我希望这些额外的信息对某人有帮助。