CakePHP 3 ではアソシエーションを設定し関連データを取得することが出来る。 CakePHP 2 以前もあった仕組みであるが hasMany 若しくは belongsToMany で関連付けたデータを contain にして where で絞り込もうとすると失敗する:

$this->find()
    ->contain(['Comments'])  // Post has many comments とする
    ->where(['Comments.type' => 1]);  // 指定できそうに見えるが失敗!!

この PostbelongsTo の場合は内部的に INNER JOIN 若しくは OUTER JOIN された SQL が発行されるので大丈夫なのだが hasMany 若しくは belongsToMany複数の SQL に分割して発行されるので、最初の SQL に Comments が存在せず、条件を指定してもそれが最初の SQL に対し指定されてしまい「存在しないカラムに対し条件を指定している」ことになり失敗してしまう:

# 内部的にこのように分けて発行されるので最初の SQL には Comments は存在しない!!
SELECT * FROM articles;
SELECT * FROM comments WHERE article_id IN (1, 2, 3, 4, 5);

これを避けるために contain に対し以下のようにクロージャを渡すことにより 2 つ目の SQL に対し条件を渡すことが出来る:

$query = $articles->find()->contain([
    'Comments' => function ($q) {
       return $q->where(['Comments.type' => 1]);
    }
]);

つまり contain している Entity のアソシエーションがどの関係であるかを思い浮かべて適切なコードを書かなければならない。 この手の O/R マッパーを使用する際はしばしば内部で吐かれる SQL を dump しながら挙動を確認しなければならないのが辛い所ではある。