2010-02-22 11 views
11

में मेरे पास एक केकपीएचपी 1.3 ऐप है और वास्तव में डेटा लाने के लिए Containable behavior का आनंद लें।केकपीएचपी मॉडल: COUNT (*) कंटेनर

मान लें कि मेरे पास टिप्पणियों के साथ कई से अधिक संबंधों में पोस्ट हैं। मैं सभी पदों और संबंधित टिप्पणियों की एक सूची (पेजिनेशन के लिए) क्वेरी करने के लिए कंटेनर का उपयोग करता हूं। लेकिन मुझे केवल दिलचस्पी है कि प्रत्येक पोस्ट में कितनी टिप्पणियां हैं। मुझे टिप्पणियों की सभी पंक्तियों को लाए बिना इस क्वेरी को कंटेनबल के साथ प्राप्त करने का कोई तरीका नहीं मिला। मैंने कोशिश की:

$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'=>''), 
     ); 

था, लेकिन इस एक त्रुटि में परिणाम है क्योंकि hasMany रिश्ते, स्वतंत्र रूप से पूछे जाते हैं, इसलिए उत्तर तालिका पोस्ट प्रविष्टियों के लिए क्वेरी में नहीं है। मैं एक पोस्ट की टिप्पणियों की संख्या कैसे गिन सकता हूं?

'counterCache' => true

हर बार कुछ भी करेंगे:

उत्तर

11

ठीक है, यह करने के लिए सबसे अच्छा तरीका है posts तालिका में एक क्षेत्र comment_count कहा जाता है की स्थापना की और टिप्पणी मॉडल $ belongsTo पोस्ट सरणी के लिए इस कुंजी को जोड़ने के लिए है टिप्पणियों के साथ हो रहा है, संबंधित पोस्ट में comment_count फ़ील्ड अपडेट किया जाएगा (वास्तव में, यह केवल जोड़ने या हटाने के बजाय हर बार याद करता है)।

यह बेहतर है, क्योंकि जब आप उपयोगकर्ता के लिए डेटा प्राप्त करते हैं, तो इसका तरीका तेज़ होता है और टिप्पणियां तालिका को भी स्पर्श नहीं करता है। चूंकि आप कंटेनएबल व्यवहार का उपयोग कर रहे हैं, मुझे लगता है कि आप जिस गति और हल्के वजन की तलाश कर रहे हैं वह है।

+3

यह एक अच्छा विचार है, लेकिन यह अधिक जटिल प्रश्नों के लिए समस्या का समाधान नहीं करता है, जहां एक पंक्ति से जुड़ी गिनती को काम नहीं करेगा (उदाहरण के लिए एक रिपोर्टिंग सिस्टम जहां उपयोगकर्ता द्वारा कुछ शर्तों को चुना जाता है)। क्या कंटेनर का उपयोग करके गिनती पाने का कोई और तरीका नहीं है? – Zxaos

6

मेरे पास एक ही प्रश्न था। जवाब दिया गया कि PawelMysior महान था और समाधान के लिए नेतृत्व।

मुझे केकेपीएचपी पुस्तक में कुछ और विवरण मिले: 3.7.4.1.1 counterCache - Cache your count()। यह सहायक था लेकिन अभी भी थोड़ा अस्पष्ट था। दूसरों के लिए, मैं कुछ और विवरण देना चाहता हूं।

मेरे पास दो टेबल हैं: पोस्ट और छवि। जब मैंने एक पोस्ट में एक छवि जोड़ा, तो मैं छवि सूची पर अतिरिक्त गिनती क्वेरी चलाने की आवश्यकता के बिना पोस्ट इंडेक्स सूची पर प्रत्येक पोस्ट को प्रदर्शित करने के लिए कितनी छवियां ट्रैक करना चाहता हूं।

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_countposts तालिका में चला जाता है। 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 
     ) 
    ); 
} 

सूचना है कि counterCacheImage मॉडल में जोड़ा जाता है। 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 कर वहाँ गिनती लगता है क्योंकि यह स्वतः Post परिणामों में एक क्षेत्र है कुछ भी विशेष करने की कोई जरूरत नहीं है। नीचे image_count पर ध्यान दें।

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 जोड़ने के लिए, Post में गिना जाता है शून्य हो जाएगा जब तक एक और Image जोड़ा जाता है। बिंदु पर, केकपीएचपी वास्तविक गणना करेगा और को सही राशि पर अपडेट करेगा।

मुझे आशा है कि यह अतिरिक्त जानकारी किसी के लिए सहायक होगी।

संबंधित मुद्दे