2017-08-24 14 views
0

私はCakePHP 3.3.15アプリでグローバル検索のメシニズムを実装しようとしています - これは親テーブルの値を検索し、関連するすべてのテーブルを検索します同じ値。 matching()を使用していますが、を複数の一致()を1つのクエリオブジェクトに結合する方法が見つからない場合は、ORを使用してください。CakePHP 3.3.15多重一致()OR

matching()は結果セットを絞り込み、matching()を連続して呼び出すと、以前のmatching()呼び出しで変更されたオブジェクトが使用されるようです。

これは私が持っているものです。

$query = $this->$modelName->find();   
$query->matching('Colonies', function ($q) { 
       return $q->where(['OR' => [ 
        'Colonies.colony_id' => 10003, 
        'Colonies.project_id' => 6 
       ]]); 
      }); 
debug($query->count()); //returns 4 entries 

$query->matching('Projects', function ($q) { 
       return $q->where(['OR' => [ 
        'Projects.id' => 1, 
        'Projects.project_status_id' => 3 
       ]]); 
      }); 
debug($query->count()); //returns 1 entry. However, when the previous matching() is removed, it will return 2 entries 
私がこれまで試してみました他に何

  1. innerJoinWith()を使用しての代わりに、()に一致する - 同じ結果を、単に結果セットは、関連するフィールドを欠いています(正確にCookBookと同じように)
  2. $this->$modelName->find()->contain('ChildTable', function ($q) { return $q->where(['ChildTable.FieldName' => 'some value']});を使用すると、これはまったく動作しないようです(結果セットをフィルタリングしません)
  3. 結果セットを手作業で強制的にORビヘイビアに設定する - コードの後半でページネーションを使用しているので、結果セットを直接操作することはできません - ページングに渡すQueryオブジェクトが1つ必要です。

大変助かりました!

答えて

1

マッチングはJOINレベルに条件を適用するので、matching()条件の各セットは、独立して適用され、そしてmatching()ための両方、INNERジョイン作成レコードを除外します加入します。

ご複数matching()条件はのようなSQLを作成し、生成されたSQLをチェックしてください:あなたが探しているものを

INNER JOIN colonies ON colonies.colony_id = 10003 OR colonies.project_id = 6 
INNER JOIN projects ON projects.id = 1 OR projects.project_status_id = 3 

はAを使用する必要があります)LEFT自体はexcudeないレコードを行う参加するように、結合、あなたはまた、メインモデルの主にグループに加入する必要があるかもしれないの性質上へ

$query = $this->$modelName 
    ->find() 
    ->leftJoinWith('Colonies') 
    ->leftJoinWith('Projects') 
    ->where([ 
     'OR' => [ 
      'Colonies.colony_id' => 10003, 
      'Colonies.project_id' => 6, 
      'Projects.id' => 1, 
      'Projects.project_status_id' => 3 
     ] 
    ]) 
    ->group($modelName . '.id'); 

:B)が結合テーブルに基づいてレコードをフィルタリングすることができるようにするために、メインクエリに条件を適用するにはキーその結果を避けるために

+0

参照してください。ありがとうございました!私は ' - > contains()'をチェーンに追加して、関連するテーブル値を結果セットに含める必要がありました。 btw。この解決策は私の心を一点で超えましたが、多対多関係の場合にはCakePHPがルックアップテーブルを扱うとは思わなかったのです。思ったよりスマートに見える –