2012-10-24 26 views
5

我有三種型號,用戶,評論頁面如何最小化CakePHP中的「包含」查詢?

用戶有許多評論評論屬於

所有型號使用containable行爲,默認爲recursive -1

如果我呼籲評論一個find()查詢,與包含請求包括模型的領域,這正確返回使用結果的單個查詢,自動地加入表給用戶。

如果我請從用戶模型類似的查詢(含有註釋Comment.Page),其結果是到源極評論查詢,隨後每註釋查詢以請輸入相關的頁面

有沒有辦法配置模型來維持JOIN優化?我假設相關模型的belongsTo聲明(評論)將貫穿到主機模型(用戶)。

UPDATE

我要澄清,我的問題用我的實際案例研究的簡化版本。雖然我需要的最小的解決方案將包括初始型號的hasMany型號屬於關聯型號結構,我也期待在一個或多個附加屬於關聯模型解下來的鏈(其,我雖然會自動使用LEFT JOIN,因爲這是可行的)。

回答

1

那麼你問是否有更簡單的方法來包含所有的查詢?如果你想包含當前控制器中的所有內容。您可以在beforeFilter()回調中執行包含,它將應用於該控制器中的所有查詢。

+1

嗨科爾比。你在實踐中是否有這樣的例子?正如我認爲這種方法可能有助於我自己的項目以及原始的海報。 –

+0

我相信你的控制器中的東西會包含你對整個控制器的查詢。 'function beforeFilter() \t { \t \t parent :: beforeFilter(); \t \t $ this-> Model-> contains('RelatedModelStuff'); \t \t \t} // beforeFilter' –

+0

感謝Colby,這並不完全是我以前的樣子,但beforeFilter包含的聲明是一個有用的片段,歡呼聲。 – Rhys

1

我不太清楚,如果我理解你的問題,但我認爲你有評論 - >頁面鏈接的許多SQL調用的問題?如果這是正確的,那麼

  1. 嘗試linkable behaviour從而降低SQL調用和作品幾乎包含不
  2. ,或者如果它幾乎你想同樣的數據,然後在一個特定的模式,從您所在的位置創建一個功能高興HTE SQL調用(比如註釋,模型)和$this->Comment->myFindFct($params);

希望幫助

編輯從用戶模式稱之爲:一個在我腦海中的東西。您可以將關聯數組中的連接類型更改爲inner,這使得蛋糕可以單獨調用相關模型。

2

嗯,這很有趣。這是一種優化的應在覈心:)

無論如何實施,我想你可以通過建立查詢的方式有點不同得到相同的結果(也許是格式不同):

$this->User->Comment->find('all', array(
    'conditions' => array(
    'Comment.user_id' => $userId 
), 
    'contain' => array(
    'User', 
    'Page' 
) 
)); 

通過從Comment模型中搜索,它應該使用兩個左連接來加入數據,因爲它們都是1:1關係。注意:結果數組可能與從用戶模型搜索時看起來有些不同。

+0

謝謝jeremyharris。這是行得通的,但我必須澄清我的問題以證明真實的案例研究需要更多的belongsTo連接。我會牢記這一點,儘管如果我必須手動構建我的查詢,這將節省一點時間。 – Rhys

1

我找到一個很好的方法來做到這一點是創建一個custom find method

作爲一個例子,我會在您的用戶模型中創建一個方法,稱爲_findUserComments()。然後你會在這個方法裏面做所有的連接,包含等等。然後在你的控制器,無論你需要得到所有的用戶的評論,你會正是如此稱呼它:

$this->User->find('UserComments', array(
    "conditions" => array(
     'User.id' => $userId 
    ) 
)); 

我希望這有助於。

+0

謝謝Rob。我確實使用了自定義查找方法,它們非常有用,但是這仍然無法解決構建查詢(連接等)的極其手動版本的情況,以實現我將要理解的核心自動優化的內容。 – Rhys

1

如果像波紋管的模型定義:

  1. 評價模型屬於頁面和用戶。
  2. 頁屬於用戶,並有很多評論。
  3. 用戶有很多頁和評論

代碼波紋管會返回一個連接查詢:

$this->loadModel('Comment'); 
$this->Comment->Behaviors->attach('Containable'); 
$queryResult = $this->Comment->find('all', array(
    'contain' => array(
     'User', 
     'Page' 
    ) 
)); 

代碼波紋管會返回兩個查詢。頁面和用戶加入到一個查詢和所有評論中的另一個查詢

$this->loadModel('Page'); 
$this->Page->Behaviors->attach('Containable'); 
$queryResult = $this->Page->find('all', array(
    'contain' => array(
     'User', 
    'Comment' 
    ) 
)); 

,也婁代碼將返回三個查詢,每個型號:

$this->loadModel('User'); 
$this->User->Behaviors->attach('Containable'); 
$queryResult = $this->User->find('all', array(
    'contain' => array(
     'Page', 
     'Comment' 
    ) 
)); 
+0

謝謝,儘管我關心的是一個模型結構,它有多個屬於連接的鏈接,而不是屬於兩個不同模型的模型。例如。將模型1所屬的一個查詢返回到模型2,模型2屬於模型3,模型3屬於模型4。數據可以使用自定義語句在單個查詢中返回,但我的理解是核心無論如何應該處理此優化。 – Rhys

+0

如果我在這裏不理解你的陳述,我很抱歉。但在你的問題上,「用戶有很多評論,評論屬於頁面」等同於我上面的模型定義(見第3點和第1點)。而且,如果您從User模型調用的查詢結果已通過返回三個查詢進行優化(而不是每次評論對頁面重複查詢)。 – Habibillah

+0

對不起,我認爲我的_update_澄清了更深入的案例研究(鏈式歸屬),當我意識到原始案例研究的解決方案在未真正涵蓋我的問題的上下文的情況下可以解決 – Rhys