【发布时间】:2019-06-12 14:55:11
【问题描述】:
我试图通过允许控制器能够使用名字和姓氏进行搜索来使该控制器更具动态性。目前,控制器仅按名字、姓氏和电子邮件地址进行搜索。我希望能够在过滤器中输入“$filter=Chris smith”并查询“Chris smith”结果。
下面是我的控制器。
公共函数 getEventSessionAttendeeAction(request $request, $eventSessionId) {
$filterName = 'filter';
$searchFields = [
'o.email',
'a.email',
'a.firstName',
'a.lastName',
'a.barcode1',
'a.barcode2',
'a.id',
'o.id',
$lname = 'a.lastName',
$fname = 'a.firstName'
];
$filter = $request->get('filter');
$match_level = 0;
if ( filter_var($filter, FILTER_VALIDATE_EMAIL)) {
$searchFields = [
'a.email'
];
$match_level = 1;
}elseif(preg_match('/^[a-zA-Z\-]*$/', $filter)){
$searchFields = [
'a.lastName',
'a.firstName'
];
$match_level = 2;
}else{
$lname = 'a.lastName';
$fname = 'a.firstName';
}
try {
/** @var ApiEntity\EventSession $eventSession */
// $eventSession = $this->get('doctrine')->getRepository('KCMApiBundle:EventSession')->findOneById($eventSessionId);
// $eventAttendees = $this->getEventSessionAttendeesCheckedIn($eventSession);
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb ->select('a.firstName, a.lastName, a.relationship, a.dateOfBirth, a.barcode1, a.phoneNumber, ea.address1, ea.address2, ea.city, ea.state, ea.country, ea.postal, s.name, s.keynoteSpeaker, ci.created, \'checkin\' AS event')
->from('KCMApiBundle:EventSessionCheckin', 'ci')
->innerJoin('ci.eventSession', 's')
->innerJoin('ci.eventAttendee', 'a')
->leftJoin('a.eventAttendeeAddresses', 'ea')
->where($qb->expr()->andX(
$qb->expr()->eq('ci.eventSession', $qb->expr()->literal($eventSessionId))
));
// ->where('ci.eventSession = :sessions')
// ->groupBy('a.id', 's.id')
// ->setParameter('sessions', $eventSessionId)
$expr = $qb->expr()->orX();
foreach ($searchFields as $field){
if ($match_level === 1){
$literalFilter = $filter;
$expr->add($qb->expr()->like($field, $qb->expr()->literal($literalFilter)));
}elseif ($match_level === 2){
$literalFilter = $filter;
$expr->add($qb->expr()->eq($field, $qb->expr()->literal($literalFilter)));
}else{
$literalFilter = $filter;
$expr->add($qb->expr()->concat($lname, $qb->expr()->concat($qb->expr()->literal($literalFilter), $fname)));
}
}
$qb->andWhere($expr);
$results = $qb->getQuery()->getResult();
if ($results) {
return $this->getApi()->serialize($results);
}
return new Response(null, Response::HTTP_NOT_FOUND);
} catch (\Exception $e) {
$this->get('logger')->error($e->getMessage());
}
}
【问题讨论】:
-
您是否阅读过 Doctrine 文档中Criteria 上的部分?他们举了几个例子。此外,它们是一种以人类可读格式编写查询的独立方式的数据库引擎。如:您可以使用
Criteria创建的“查询”并将它们应用于所有支持的数据库类型,例如 MySQL、PostgreSQL、MongoDB 等。请提供有关您查找和尝试的更多信息。 -
@rkeet 我想做的是做一个查询构建器,它通过获取请求获取“名字”和“姓氏”的 URL。然后,将其作为查询传递给搜索条件中的搜索结果,例如; Chris smith(到终点)只为 chris smith 获得退货结果。现在,我的搜索只是搜索名字或姓氏,但我需要能够让用户输入“Chris Smith”和查询。我更新了我的原始味精以反映这一点。如果你能帮助我,那就太好了。
-
当然,你能先看看几个月前的an answer of mine吗?如果你能从那里弄清楚,那就太好了。如果没有,我会尝试写一个答案;)
-
(不要忘记与Hugo's answer 结合使用——这也是你需要了解的关于QB 的一个很好的步骤——当然还有QB code 和Criteria code)本身。提示:检查命名空间,DBAL QueryBuilder 不一样 ORM QueryBuilder)
-
@rkeet 我试了一下,我似乎被卡住了,除了名字和姓氏部分,我一切正常:(
标签: symfony doctrine-orm query-builder entitymanager