matching()
creates
INNER
joins
,并将条件应用于联接的
ON
子句,如果不存在匹配的名称,则会导致用户被筛选出,因此您不能使用它来创建
OR
你正在寻找的条件。
use it with
EXISTS
,大致如下:
$namesMatcher = $this->Users->Names
->find()
->select(['Names.id'])
->where(function($exp, $query) use ($search_term) {
$full_name = $query->func()->concat([
'Names.first' => 'identifier', ' ',
'Names.last' => 'identifier'
]);
return $exp
->equalFields('Names.user_id', 'Users.id')
->like($full_name, '%' . $search_term . '%');
});
$users = $this->Users->find()
->where(function($exp, $query) use ($search_term, $namesMatcher) {
return $exp
->or_(['Users.username LIKE' => '%' . $search_term . '%'])
->exists($namesMatcher);
})
->contain(['Names'])
->limit(10)
->all();
生成的查询如下所示:
SELECT
Users.id ...
FROM
users Users
WHERE
Users.username LIKE '%term%' OR
EXISTS(
SELECT
Names.id
FROM
names Names
WHERE
Names.user_id = Users.id AND
CONCAT(Names.first, ' ', Names.last) LIKE '%term%'
)
这也可以通过使用示例a来解决
LEFT
连接,这样用户记录就不会受到连接的影响(请参阅
Query::leftJoinWith()
),允许您创建
或
条件,但由于您似乎不需要进一步访问查询中的名称,因此选择它们实际上没有意义。