Jest kilka sposobów na osiągnięcie tego, jednym z nich jest pogrupowanie wyników i użycie HAVING porównać liczbę różnych tagów
$query = $this->Users
->find()
->matching('Tags', function ($query) {
return $query->where(['Tags.name IN' => ['Tag1', 'Tag2']]);
})
->group('Users.id')
->having([
$this->Users->query()->newExpr('COUNT(DISTINCT Tags.name) = 2')
]);
Spowoduje to wybranie tylko tych użytkowników, którzy mają dwa różne tagi, którymi mogą być tylko Tag1 i Tag2 ponieważ są to jedyne, które są dołączane. W przypadku name kolumna jest unikalna, zamiast tego możesz liczyć na klucz podstawowy.
IN przy okazji jest zasadniczo taki sam jak Twój OR warunki (system bazy danych rozwinie IN do OR odpowiednie warunki).