2010-10-19 32 views
1

我在我的模型中定義這些關係:爲什麼CakePHP複製我的查詢? (這是不一樣的「查詢太多」的問題,通常是問)

鉛的hasMany工作
工作HABTM員工
工作HABTM卡車

我想從我的卡車模型做了find('all'),結果限制爲:

  1. 所有的卡車,
  2. 與卡車牛逼相關聯的所有作業帽子有一定的取件日期,
  3. 分配給這些工作的員工,
  4. 和與工作相關的領導。

這裏是我的查找操作:

// app/models/truck.php 
$this->find('all', array(
    'contain' => array(
     'Job' => array(
      'Employee', 
      'Lead', 
      'conditions' => array(
       'Job.pickup_date' => $date 
      ) 
     ) 
    ) 
)); 

出於某種原因,蛋糕確實查詢兩次找到員工。這導致所有員工爲每項工作代表兩次。下面是SQL轉儲:

  1. SELECT `Truck`.`id`, `Truck`.`truck_number` 
    FROM `trucks` AS `Truck` 
    WHERE 1 = 1;
  2. SELECT `Job`.`id`, `Job`.`lead_id`, `Job`.`city`, 
         `JobsTruck`.`id`, `JobsTruck`.`job_id`, `JobsTruck`.`truck_id` 
    FROM `jobs` AS `Job` 
    JOIN `jobs_trucks` AS `JobsTruck` ON (`JobsTruck`.`truck_id` IN (2, 3) 
    AND `JobsTruck`.`job_id` = `Job`.`id`) 
    WHERE `Job`.`pickup_date` = '2010-10-06'
  3. SELECT `Lead`.`id`, `Lead`.`name`, `Lead`.`created` FROM `leads` AS `Lead` 
    WHERE `Lead`.`id` = 4
  4. SELECT `Employee`.`id`, `Employee`.`name`, `Employee`.`created`, 
         `EmployeesJob`.`id`, `EmployeesJob`.`employee_id`, 
         `EmployeesJob`.`job_id` 
    FROM `employees` AS `Employee` 
    JOIN `employees_jobs` AS `EmployeesJob` 
         ON (
          `EmployeesJob`.`job_id` = 1 AND 
          `EmployeesJob`.`employee_id` = `Employee`.`id` 
         )
  5. SELECT `Lead`.`id`, `Lead`.`name`, `Lead`.`created` FROM `leads` AS `Lead` 
    WHERE `Lead`.`id` = 4
  6. SELECT `Employee`.`id`, `Employee`.`name`, `Employee`.`created`, 
         `EmployeesJob`.`id`, `EmployeesJob`.`employee_id`, 
         `EmployeesJob`.`job_id` 
    FROM `employees` AS `Employee` 
    JOIN `employees_jobs` AS `EmployeesJob` 
         ON (
          `EmployeesJob`.`job_id` = 1 AND 
          `EmployeesJob`.`employee_id` = `Employee`.`id` 
         )

請注意,最後兩個查詢是重複的。我錯了我錯過了什麼嗎?

UPDATE
看來,Cake爲每輛卡車發送重複查詢。現在我在卡車表中有15條記錄,對leadsemployees的查詢每個都重複15次。

回答

3

我不知道爲什麼會出現重複的兩個查詢,但也許這種行爲可以幫助:

https://github.com/Terr/linkable

UPDATE

這樣的問題是衆所周知的:

+0

這看起來很有趣。我在星期一上班時會檢查一下。 – Stephen 2010-11-21 16:03:57

+0

真棒,力拓。感謝您的事實發現。 – Stephen 2010-11-24 15:54:10

+0

所以Ticket是2歲。顯然他們的目標是CakePHP 2.0來解決這個問題。現在我正在將查詢拆分爲多次調用'$ this-> find'並手動構建數據數組,這很糟糕,但是當從80個查詢轉到4個查詢時,它會減少很多。 – Stephen 2010-11-24 16:25:41

-3

你想LEFT JOIN代替JOIN。

不要問我如何在cakephp中做到這一點,我很高興我的代碼目前正常工作。 ^^

+0

問題是關於CakePHP。先生,好日子。 – Stephen 2010-11-22 22:44:17

+0

::感嘆::結果集*罰款*。更改JOIN不會解決問題。問題在於CakePHP多次觸發相同的查詢。 thaRRR11!給你。 – Stephen 2010-11-22 23:51:36

+0

所以錯了....... – c0rnh0li0 2010-11-23 00:20:48

1

沒有什麼可以將找到的Job/s加入到特定的Truck

(我希望我的解釋是不是太難理解,但CakePHP的可有時候這樣!恕我直言)

Jobs被歸因於Trucks在幾乎任意的方式(我的記憶蛋糕是可以發生的); HABTM呼叫的性質將Job/s附加到每個15 Trucks。從我的角度來看,這似乎是目前的過程;

  • 獲得所有卡車。
  • 獲取日期爲x的卡車的所有工作。
  • [問題1]將找到的Jobs附加到每個Truck(即您的15輛卡車),但每個Truck都附加一個。
  • [問題2]獲取與該工作相關的所有潛在客戶/員工,再次每個Truck

問題1:問題的根源。您可以在第二個查詢中看到(SELECT Job ...),它在ON語句中使用正確的truck_id's,但Cake不能將這些Jobs「加入」Truck,因爲它是一個不同的查詢!所以它將找到的工作加入到每個Truck

問題2:這是「真實」的問題,對蛋糕並不長構建JOIN聲明,所以沒有辦法找到Employees/Leads只爲您希望這些Trucks。這就是爲什麼它會爲每輛卡車找到它們,這是因爲您在Truck上執行FindAll

我希望這是有道理的。您需要在Jobs上查找全部內容,因爲這是查詢(pickup日期)的「中心」

$this->loadModel('Job'); 
$whatev = $this->Job->find('all', array(
    'contain' => array(
     'Job' => array(
      'Truck', 
      'Employee', 
      'Lead', 
      'conditions' => array(
       'Job.pickup_date' => $date 
      ) 
     ) 
    ) 
)); 

CakePHP的查詢,當你發現一個/所有一定的模式,最好是在中間開始,然後兩邊,如果你有一個雙HABTM關係真的只是工作。如果您希望通過卡車進行「排序」,那麼您可能必須編寫自己的查詢(模型方法)才能自己完成任務。在原始SQL中,這個查詢可能很容易,在抽象的PHP超級蛋糕中,這對於CakePHP來說是很難實現的。

快樂烘焙,正如他們所說!

+0

這看起來很有希望,但是你的意思是包含Job on Job? – Stephen 2010-11-24 15:36:43

+0

我有一個祕密。還有另一種關係:'卡車 - > hasMany - > TruckLog'。 (爲了簡單起見,我將它從示例中排除)當移動查詢以圍繞'Job'而不是'Truck'集中時,我開始通過'TruckLog'獲得同樣的問題(對於與卡車相關的每項工作都重複查詢)。 – Stephen 2010-11-24 16:22:59

+0

你是對的工作包含工作,這是我的疏忽。特別是對於額外的HABTM關係TruckLog,您幾乎肯定需要創建一個模型方法,以準確找到您想要的內容。您可能需要使用$ Model-> query()來查詢您自己的SQL查詢,並且可能使用子查詢/ s在一個查詢中實現此目的(性能可能更快)。或者你可能有一個模型方法可以單獨找到它們,並使用數組合並(http://book.cakephp.org/view/679/merge)來處理每個項目的結果。 – Ghostpsalm 2010-11-25 00:37:08