I have one MongoDb document with 3 fields message, author, sendAt, i have created a query builder to count all DB entries on this document and if there is more than 20 entries, I'm trying to delete the oldest one.
sendAt is the current dateTime when the message is send ("sendAt" : ISODate("2016-01-21T08:53:00Z"))
I have an unfinished query builder
public function deleteOldestMessage()
{
return $this->createQueryBuilder()
->delete('m')
->from('Messages', 'm')
->where('m.sendAt = ')
->execute();
}
But i really don't know what i should add on the where condition.
I should maybe order DESC the sendAt field and delete the first on the list ?
How can I tell the query builder to delete the oldest one ?
Thanks,
You need first to select the oldest one then you can delete it like this :
$qb->select('m')
->from('Messages', 'm')
->orderBy('m.sendAt', 'DESC');
$messages = $qb->getResult();
thene
if(count($messages) >= 20){
//get the first element of array which is the oldest one
$lastMessage = current($messages);
$em->remove($lastMessage);
}
You can try something like:
$qb = $em->createQueryBuilder();
$messages = $qb->select('m')
->from('Messages', 'm')
->orderBy('m.sendAt', 'ASC')
->getQuery()
->getResult()
;
// You will receive array where in the top will be the oldest message.
if (count($messages) > 20) {
// And in your desired case, you can remove just one oldest message.
$messageToDelete = array_shift($messages);
$em->remove($lastMessage);
$em->flush();
}
You use sql query builder options instead of mongodb.
return $this->createQueryBuilder()
->remove()
->sort('sendAt', 'asc')
->getQuery()
->getSingleResult()
->execute();
Related
I try to delete some data with Doctrine\DBAL\Connection, I want to delete the duplicate data so I have to delete n-1 data (If n data are the same).
public function deleteDuplicateData(array $data) : bool
{
$qb = $this->connection->createQueryBuilder();
$qb->delete('myTable')
->where('id= :id')
->setParameter('id', $data['id'])
->setMaxResults($data['n']-1)
;
return $qb->execute();
}
However the ->setMaxResults($data['n']-1) doesn't work, when I run my code all data are deleted. I tried this ->setMaxResults($data['n']-1) but it does'nt work so I think the method ->setMaxResults() doesn't work for the delete method.
I cant comment, so sry for this ^^
Is it possible to count the rows with duplicate data in your DB System + Do they have the same ID? If yes, you could store the ammount - 1 to a variable $duplicatedRows and use a for loop like:
for($i;$<=$duplicatedRow;$i++){
//Your Code to delete something
}
setMaxResults works only in some cases. It seems to ignore it if it's not managed.
check the Doctrine doc : https://www.doctrine-project.org/projects/doctrine1/en/latest/manual/dql-doctrine-query-language.html#driver-portability
use below function for set limit
public function deleteDuplicateData(array $data) : bool
{
$limit = 10;
$qb = $this->connection->createQueryBuilder();
$qb->delete('myTable')
->where('id= :id')
->setParameter('client_id', $data['id'])
->setMaxResults($limit);
return $qb->execute();
}
I have the following code
$qb = $this->createQueryBuilder('cs')
->update()
->set('cs.is_active', 1)
->where('cs.reward_coupon = :reward_coupon')
->setMaxResults($limit)
->setParameter('reward_coupon', $rewardCoupon);
$qb->getQuery()->execute();
This doesn’t apply the LIMIT in the resultant query.
setMaxResult() has to be your last Doctrine statement in order to properly works
example :
$qb = $this->createQueryBuilder('cs')
->update()
->set('cs.is_active', 1)
->where('cs.reward_coupon = :reward_coupon')
->setParameter('reward_coupon', $rewardCoupon)
->setMaxResults($limit);
return $qb->getQuery()->execute();
I think that this may help
$limit=50;
$i=0;
$qb = $this->createQueryBuilder('cs')
->update()
->set('cs.is_active', 1)
->where('cs.reward_coupon = :reward_coupon')
->setParameter('reward_coupon', $rewardCoupon)
->setFirstResult($i)
->setMaxResults($limit);
$qb->getQuery()->execute();
I have a query that joins several tables,
$qb = $dbm->createQueryBuilder();
$qb->select('job', 'tasks')
->from('MyJobBundle:Job', 'job')
->innerJoin('job.tasks', 'job_tasks');
This works as expected and I have an array of tasks for every job. I want to just count the number of tasks but not return them. Something like,
$qb = $dbm->createQueryBuilder();
$qb->select('job', 'count(job.tasks) as num_tasks')
->from('MyJobBundle:Job', 'job')
->innerJoin('job.tasks', 'job_tasks');
How can I do this?
Try this :
$qb->select('count(job_tasks) as num_tasks')
->from('MyJobBundle:Job', 'job')
->innerJoin('job.tasks', 'job_tasks')
->groupBy('job')
->getQuery()
->getResult();
That should return the counts for each job value
I'm trying to get a single row returned from a native query with Doctrine. Here's my code:
$rsm = new ResultSetMapping;
$rsm->addEntityResult('VNNCoreBundle:Player', 'p');
$rsm->addFieldResult('p', 'player_id', 'id');
$sql = "
SELECT player_id
FROM players p
WHERE CONCAT(p.first_name, ' ', p.last_name) = ?
";
$query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
$query->setParameter(1, $name);
$players = $query->getResult();
That last line returns a list of players but I just want one result. How do I do that?
You can use $query->getSingleResult(), which will throw an exception if more than one result are found, or if no result is found. (see the related phpdoc here https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L791)
There's also the less famous $query->getOneOrNullResult() which will throw an exception if more than one result are found, and return null if no result is found. (see the related phpdoc here https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L752)
Both getSingleResult() and getOneOrNullResult() will throw an exception if there is more than one result.
To fix this problem you could add setMaxResults(1) to your query builder.
$firstSubscriber = $entity->createQueryBuilder()->select('sub')
->from("\Application\Entity\Subscriber", 'sub')
->where('sub.subscribe=:isSubscribe')
->setParameter('isSubscribe', 1)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
->getSingleScalarResult() will return a single value, instead of an array.
I just want one result
implies that you expect only one row to be returned. So either adapt your query, e.g.
SELECT player_id
FROM players p
WHERE CONCAT(p.first_name, ' ', p.last_name) = ?
LIMIT 0, 1
(and then use getSingleResult() as recommended by AdrienBrault) or fetch rows as an array and access the first item:
// ...
$players = $query->getArrayResult();
$myPlayer = $players[0];
I use fetchObject() here a small example using Symfony 4.4
<?php
use Doctrine\DBAL\Driver\Connection;
class MyController{
public function index($username){
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder
->select('id', 'name')
->from('app_user')
->where('name = ?')
->setParameter(0, $username)
->setMaxResults(1);
$stmUser = $queryBuilder->execute();
dump($stmUser->fetchObject());
//get_class_methods($stmUser) -> to see all methods
}
}
Response:
{
"id": "2", "name":"myuser"
}
To fetch single row
$result = $this->getEntityManager()->getConnection()->fetchAssoc($sql)
To fetch all records
$result = $this->getEntityManager()->getConnection()->fetchAll($sql)
Here you can use sql native query, all will work without any issue.
I have the following code in my Symfony2 Repository Class...
$query = $this->createQueryBuilder('foo')
->where('foo.bar = :id')
->setParameter('id', $myID)
->getQuery();
How do I get the number of rows found by the database?
Thanks in advance
You need to execute DQL to do something you want.
$query = $this->createQueryBuilder()
->from('foo', 'f')
->where('foo.bar = :id')
->setParameter('id', $myID)
->getQuery();
$total = $query->select('COUNT(f)')
->getQuery()
->getSingleScalarResult();
I think you can do something like that:
$query = $this->createQueryBuilder()
->select('COUNT(f.id)')
->from('foo', 'f')
->where('foo.bar = :id')
->setParameter('id', $myID)
->getQuery();
$total = $query->getSingleScalarResult();
You execute the query then get the results. When you have the results, you get the number of record by doing a count on the results:
$results = $query->getResult();
$resultCount = count($results);
If you are concerned with paging, like getting 25 records out of the total. Then, you have two choices.
You perform the query twice, one time to get total results, another time to retrieve only 25 results using the method setFirstResult and setMaxResults. This method setFirstResult enable you to set the offset and the second, setMaxResults, number of records. The following code will give you results ranging from 25 to 50, it's the second page if you use 25 records by page.
$query->setFirstResult(25);
$query->setMaxResults(25);
You can check doctrine-extensions for Doctrine2 which have paginator support. These extensions have been made by one of the developer of Doctrine2. You can review these here.
Hope this help.
Regards,
Matt
I think this is as concise as it gets:
$qb = $repo->createQueryBuilder('entity');
$qb->select('COUNT(entity)');
$count = $qb->getQuery()->getSingleScalarResult();
Where $repo is of type Doctrine\ORM\EntityRepository