I'm trying to do this SQL query with Doctrine QueryBuilder:
SELECT * FROM events WHERE NOT id in (SELECT event_id FROM ues WHERE user_id = $userID)
The UserEventStatus has foreign keys from User and event, as well as an integer for status.
I now want to query all events that dont have an entry in UserEventStatus from an particular User.
My function for this in the EventRepository looks like this:
public function getUnReactedEvents(int $userID){
$expr = $this->getEntityManager()->getExpressionBuilder();
$originalQuery = $this->createQueryBuilder('e');
$subquery= $this->createQueryBuilder('b');
$originalQuery->where(
$expr->not(
$expr->in(
'e.id',
$subquery
->select('ues.user')
->from('App/Entity/UserEventStatus', "ues")
->where(
$expr->eq('ues.user', $userID)
)
)
)
);
return $originalQuery->getQuery()->getResult();
}
But i get an error that says:
Error: Method Doctrine\Common\Collections\ArrayCollection::__toString() must not throw an exception, caught ErrorException: Catchable Fatal Error: Object of class Doctrine\ORM\EntityManager could not be converted to string (500 Internal Server Error)
Can anyone help me or point me to right point in the docs? Cause i failed to find something that describes my problem.
And another thing is, that I don't know if its possible, but it would be nice. Can I somehow make direct Object requests? I mean not with the string App/Entity/UserEventStatus but with something like UserEventStatus::class or something.
Thanks for your help in advance. :)
EDIT: It has to be $originalQuery->getQuery()->getResult() of course.
If its like it was with $subquery instead i recive [Semantical Error] line I0, col 41 near 'App/Entity/UserEventStatus': Error: Class 'App' is not defined. (500 Internal Server Error)
Second EDIT:
$expr = $this->getEntityManager()->getExpressionBuilder();
$queryBuilder = $this->createQueryBuilder('e');
$subquery= $this->createQueryBuilder('b')
->select('ues.user')
->from('UserEventStatus', "ues")
->add('where', $expr->eq('ues.user', $userID));
$originalQueryExpression = $expr->not($expr->in('e.id', $subquery));
$queryBuilder->add('where', $originalQueryExpression);
return $queryBuilder->getQuery()->getResult();
Third EDIT: Thanks to #Dilek I made it work with a JOIN. This is the final Query:
$queryBuilder = $this->createQueryBuilder('e')
->leftJoin('App\Entity\UserEventStatus', 'ues', 'WITH', 'ues.user=:userID')
->setParameter('userID', $userID)
->where($expr->orX($expr->not(
$expr->eq('e.id','ues.event')
),
$expr->not($expr->eq('ues.user', $userID)))
);
return $queryBuilder->getQuery()->getResult();
Building AND WHERE into a Query
public function search($term)
{
return $this->createQueryBuilder('cat')
->andWhere('cat.name = :searchTerm')
->setParameter('searchTerm', $term)
->getQuery()
->execute();
}
simple is: ->where('cat.name = :searchTerm')
UPDATE :
I think you need to use where in
$qb->add('where', $qb->expr()->in('ues.user', $userID));
And WHERE Or WHERE
Related
I need to execute the following request to the MySQL server from symfony.
SELECT count(DISTINCT hotel_id) FROM symfony.search_result where request_id=#requrst_id
Code:
In controller:
$qwery2=$repository->hotelsCount($searchId);
Function:
public function hotelsCount($requestId){
$qb = $this->createQueryBuilder('self');
$qb->select('count(hotel_id)')
->where('self.request_id=:req_id')
->setParameter('self.req_id',$requestId)->getQuery()->getResult();
$rez=$qb->getQuery()->getSingleScalarResult();
var_dump($rez);
return $rez->fetchAll();
}
But i got error:
[Semantical Error] line 0, col 13 near 'hotel_id) FROM': Error: 'hotel_id' is not defined.
Table:
Use count(self.hotel_id) in your select
or count(self.hotelId). And in your where: self.reqId < check the entitys for that
I'm still new myself, so I admit I didn't completely follow your code, but try single quotes around 'hotel_id'
Try this, in this case, entity name is "SearchResult" and bundle name is "AppBundle", change it if is needed.
public function hotelsCount($requestId) {
$qb = $this->createQueryBuilder();
$qb->select('count(p.hotel_id)');
$qb->from('AppBundle:SearchResult', 't')
->where('p.request_id = :id')
->setParameter('id', $requestId);
$count = $qb->getQuery()->getSingleScalarResult();
return $count;
}
So, I'm new to doctrine, and I'm trying to do a basic joint, but I guess I'm missing something, on my entities or I don't know for sure.
Doctrine Repository:
$queryBuilder = $this->createQueryBuilder()
->select('c.*, a.*')
->from('My\Entity\CompanyAdminNotes', 'c')
->innerJoin('Administrators','a','a.id = c.admin_id')
->where('c.admin_id = :admin_id')
->setParameter('admin_id', $id);
return $queryBuilder->getQuery()->getResult();
And I get the following error
Message: [Semantical Error] line 0, col 76 near 'a,
My\Entity\CompanyAdminNotes': Error: Identification Variable
Administrators used in join path expression but was not defined
before.
I'm not sure if my query it's wrong or something else isn't set. Can you guys give me a hint?
try to change this:
->innerJoin('Administrators','a','a.id = c.admin_id')
to this:
->innerJoin('My\Entity\Administrators','a','a.id = c.admin_id')
Because It need the path as you done into the from
UPDATE
Trying another solution like this:
$queryBuilder = $this->createQueryBuilder('c')
->select('c, a')
->from('My\Entity\CompanyAdminNotes', 'c')
->innerJoin('My:Administrators','a','a.id = c.admin_id')
->where('c.admin_id = :admin_id')
->setParameter('admin_id', $id);
Is there any way to alias fields when using partial object syntax in Doctrine 2?
I know I can do this:
$this->createQueryBuilder('user')->select([
'user.id AS id',
'user.firstName AS first_name',
'user.lastName AS last_name',
'user.email AS email',
'user.dateCreated AS date_created'
])->getQuery()->getArrayResult();
However I need to use the partial object syntax in order for doctrine to retrieve the result in a nested relational heirarchy:
$this->createQueryBuilder('team')
->select('PARTIAL team.{id, name, dateCreated}, s, PARTIAL e.{id, name}')
->innerJoin('team.session', 's')
->innerJoin('s.event', 'e')
->getQuery()->getArrayResult();
I dug around in Doctrine\ORM\Internal\Hydration\ArrayHydrator but didn't see any hooks or anything, and it doesn't look like Doctrine has a postSelect event or something that would allow me to implement my own mutation.
Thanks for any help!
Not very efficient, but I ended up subclassing the ArrayHydrator and mutating the keys myself.
Hopefully there is a better way, if not I hope this helps someone
The problem is not just about alias, it's also about bracket. Basically, Partial object syntax is very poor and does not allow aliases or brackets. It expects for a coma or the end of the list, and everything else will throw a syntax error.
I wanted to retrieve a partial object collection using a SUM() function like this
public function findByCompetition(array $competition)
{
$competitionField = $competition['field'] ?? 'Id';
$competitionValue = $competition['value'] ?? 0;
$teamsCompStatsByComp = $this->createQueryBuilder('t')
->select('partial t.{Id, competitionId, competitionOldId, teamId, teamOldId, SUM(goalsAttempted) goalsAttempted}')
->where('t.'.$competitionField.' = ?1')
->groupBy('t.teamId')
->orderBy('t.Id', 'ASC')
->setParameter('1', $competitionValue)
->getQuery()
->getResult()
;
return new ArrayCollection($teamsCompStatsByComp);
}
But got the same error
[Syntax Error] line 0, col 85: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_CURLY_BRACE, got '('
I had to retrieve data as an array, use IDENTITY() on Foreign Key, then manually hydrate my entities
public function findByCompetition(array $competition)
{
$competitionField = $competition['field'] ?? 'Id';
$competitionValue = $competition['value'] ?? 0;
$teamsCompStatsByComp = $this->createQueryBuilder('t')
->select('t.Id, IDENTITY(t.competitionId) competitionId, t.competitionOldId, IDENTITY(t.teamId) teamId, t.teamOldId, SUM(goalsAttempted) goalsAttempted')
->where('t.'.$competitionField.' = ?1')
->groupBy('t.teamId')
->orderBy('t.Id', 'ASC')
->setParameter('1', $competitionValue)
->getQuery()
->getResult()
;
foreach ($teamsCompStatsByComp as $key => $teamCompStats) {
$teamsCompStatsByComp[$key] = new TeamStatistics($teamCompStats);
}
return new ArrayCollection($teamsCompStatsByComp);
}
I think we should open an issue on Github to improve partial syntax behavior.
I was following the Symfony2 blog tutorial part 4
and I encountered this error when I tried to query the post's comments:
public function postAction($id) {
$em = $this->getDoctrine()->getEntityManager();
$post = $em->getRepository('BlogBundle:Post')->find($id);
if (!$post) {
throw $this->createNotFoundException('Unable to find Blog post.');
}
$comments = $em->createQueryBuilder('c')
->select('c')
->where('c.post = :post_id')
->addOrderBy('c.created')
->setParameter('postId', $id)
->getQuery()
->getResult();
return $this->render('BlogBundle:Default:post.html.twig', array(
'post' => $post,
'comments' => $comments
));
}
I get the following error:
"[Semantical Error] line 0, col 15 near 'c.post = :post_id': Error:
Class 'c' is not defined."
The link to the tutorial you gave doesn't work for me so I can't see the context of what your are doing but...
The parameter for createQueryBuilder() is the name of the table so you have a table called 'c'. This seems an odd name for a table.
In your query your should be selecting fields from the table, not selecting the table.
Hope that helps but if you can give a link that works I can better see what you're trying to acheive.
You can not call createQueryBuilder directly on EntityManager because it does not know what c is. This is because you just copy&paste without context and code was invoked inside repository class in tutorial. Not in controller.
Try this
$comments = $em->getRepository('BlogBundle:Comment')->createQueryBuilder('c')
->select('c')
->where('c.post = :post_id')
->addOrderBy('c.created')
->setParameter('postId', $id)
->getQuery()
->getResult();
Or add method for fetching comments into PostRepository similarly as in tutorial.
You should speify the Entity you need:
$comments = $em->createQueryBuilder('c')
->from('BlogBundle:Comment', 'c') // I suppose your entity is Comment
->select('c')
->where('c.post = :post_id')
->addOrderBy('c.created')
->setParameter('postId', $id)
->getQuery()
->getResult();
I am trying to filter out admins that have a super admin role. Why is the following not working?
public function findAdmins()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('a')
->from('MyBundle:Admin', 'a')
->where($qb->expr()->notIn('ROLE_SUPER_ADMIN', 'a.roles'));
$result = $qb->getQuery()->execute();
return $result;
}
It will give me the following error:
[Syntax Error] line 0, col 68: Error: Expected Literal, got 'a'
The DQL-query looks like this:
SELECT a FROM MyBundle:Admin a WHERE ROLE_SUPER_ADMIN NOT IN(a.roles)
Role itself is not an entity. It is simply an array of strings.
$roles = array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN)'
Try use MEMBER OF operator
$qb
->select('a')
->from('MyBundle:Admin', 'a')
->where(':role NOT MEMBER OF ad.roles')->setParamete('role', 'ROLE_SUPER_ADMIN');
Update.
The only solution found is to check serialized string in db with LIKE. Details here
Don't mix column name with table name
Try this,
$qb
->select('a')
->from('MyBundle:Admin', 'ad')
->where($qb->expr()->notIn('ROLE_SUPER_ADMIN', 'ad.roles'));
It should be like,
SELECT a FROM MyBundle:Admin ad WHERE ROLE_SUPER_ADMIN NOT IN(ad.roles)