2010-02-22 27 views
11

Tôi có ứng dụng CakePHP 1.3 và thực sự thích Containable behavior để tìm nạp dữ liệu.Mô hình CakePHP: COUNT (*) trong Có thể chứa

Giả sử tôi có bài đăng trong mối quan hệ một-nhiều với nhận xét. Tôi sử dụng Có thể chứa để truy vấn (để phân trang) một danh sách tất cả các Bài đăng và các Nhận xét thuộc về. Nhưng tôi chỉ quan tâm đến số lượng nhận xét mà mỗi bài đăng có. Tôi đã không tìm thấy bất kỳ cách nào để đạt được truy vấn này có thể chứa được mà không cần tìm nạp tất cả các dòng Nhận xét. Tôi đã thử:

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

kết quả trong 'Mô hình' Nhận xét "không được liên kết với thông báo lỗi" Tính ".

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

không hoạt động, bộ kết quả chứa trường hợp cuối cùng chứa trường đếm, nhưng có số lượng tất cả các nhận xét không chỉ là số nhận xét.

đoán khác của tôi là

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

nhưng kết quả này trong một lỗi, vì mối quan hệ hasMany được truy vấn một cách độc lập, vì vậy bảng trả lời không có trong truy vấn cho các mục bài viết. Làm cách nào tôi có thể đếm số Nhận xét mà Bài đăng có?

Trả lời

11

Vâng, cách tốt nhất để làm điều này là để thiết lập một lĩnh vực được gọi comment_count trong bảng posts và thêm phím này để mô hình Comment $ belongsTo bài viết mảng:

'counterCache' => true

Mỗi khi bất cứ điều gì sẽ đang xảy ra với các bình luận, trường comment_count trong bài liên quan sẽ được cập nhật (thực ra, nó sẽ đếm lại mọi lúc, thay vì chỉ thêm hoặc xóa).

Tốt hơn, bởi vì khi bạn tìm nạp dữ liệu cho người dùng, cách của nó nhanh hơn và thậm chí không chạm vào bảng nhận xét. Vì bạn đang sử dụng hành vi Có thể chứa, tôi đoán tốc độ và trọng lượng nhẹ là những gì bạn đang tìm kiếm.

+3

Đó là một ý tưởng hay, nhưng nó không giải quyết được vấn đề cho các truy vấn phức tạp hơn trong đó việc đếm số liên kết với một hàng sẽ không hoạt động (ví dụ như hệ thống báo cáo trong đó người dùng chọn). Không có cách nào khác để đếm được bằng cách sử dụng có thể chứa được không? – Zxaos

6

Tôi có cùng một câu hỏi. Câu trả lời mà PawelMysior đưa ra là tuyệt vời và dẫn đến giải pháp.

Tôi tìm thấy một số chi tiết khác trong CakePHP Book: 3.7.4.1.1 counterCache - Cache your count(). Điều này là hữu ích nhưng vẫn còn một chút mơ hồ. Vì lợi ích của người khác, tôi muốn cung cấp thêm một số chi tiết.

Tôi có hai bảng: Bài đăng và hình ảnh. Khi tôi thêm một hình ảnh vào một bài đăng, tôi muốn theo dõi xem có bao nhiêu hình ảnh mà mỗi bài đăng đã hiển thị trên danh sách Chỉ mục bài đăng mà không cần chạy truy vấn đếm bổ sung trên bảng Hình ảnh.

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; 

Lưu ý rằng image_count đi vào bảng posts. Không có gì đặc biệt là cần thiết trong bảng 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 
     ) 
    ); 
} 

ý rằng counterCache được thêm vào mô hình Image. Không có gì đặc biệt là cần thiết trong mô hình 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') 
     ) 
    ) 
)); 

Bây giờ khi chúng ta làm một find không cần phải làm bất cứ điều gì đặc biệt để tìm ra đếm vì nó tự động là một lĩnh vực trong Post kết quả. Hãy chú ý đến số image_count bên dưới.

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 
        ) 
       ) 
     ) 
) 

Một điều cần lưu ý, nếu bạn thêm counterCache đến một cấu trúc cơ sở dữ liệu hiện có, đếm trong Post sẽ không đến Image khác được thêm vào. Tại thời điểm này, CakePHP sẽ thực hiện đếm và cập nhật số image_count với số tiền chính xác.

Tôi hy vọng thông tin bổ sung này hữu ích cho ai đó.

Các vấn đề liên quan