web-dev-qa-db-fra.com

Le Générateur de requêtes et Grouper sur sur deux colonnes dans Symfony2/Doctrine génèrent des doublons

Je crée un paquet de messages dans lequel les messages sont regroupés par contacts. Sur ma page d'index, j'affiche différents threads. Lorsque vous cliquez sur un fil de discussion, tous les messages échangés entre vous et votre contact s'affichent. J'utilise un générateur de requêtes pour afficher les threads sur ma page d'index:

$qb = $this->createQueryBuilder('m')
    ->where('m.from = ?1 or m.to = ?1')
    ->groupBy('m.to, m.from')
    ->orderBy('m.date', 'DESC')
    ->setParameter(1, $user->getId())
    ->setMaxResults($pagination) // limit
    ->setFirstResult($pagination * $page) // offset
;

Si j'ai 3 entrées, par exemple:

+----+------+----+
| id | from | to |
+----+------+----+
| 1  | 1    | 2  |
+----+------+----+
| 2  | 2    | 1  |
+----+------+----+
| 3  | 1    | 2  |
+----+------+----+

Je m'attends à:

+----+------+----+
| id | from | to |
+----+------+----+
| 3  | 1    | 2  |
+----+------+----+

Mais je reçois:

+----+------+----+
| id | from | to |
+----+------+----+
| 2  | 2    | 1  |
+----+------+----+
| 3  | 1    | 2  |
+----+------+----+

J'ai trouvé un moyen de le faire avec SQL, en utilisant le même alias pour from_id et to_id:

SELECT id, from_id as c, to_id as c FROM Message WHERE c = 1 GROUP BY from_id, to_id

Mais je ne sais pas comment faire avec Doctrine.

MODIFIER:

En attendant d'avoir une meilleure idée, j'utilise une touche pour "grouper par" facilement.

// entity

/**
* @ORM\Column(name="key", type="string", length=40)
*/
private $key;

/**
 * @ORM\PrePersist()
 */
public function setOnPrePersist()
{
    if($this->from < $this->to) {
        $key = $this->from . 't' . $this->to;
    } else {
        $key = $this->to . 't' . $this->from;
    }

    $this->key = $key;
}

// query builder

$qb = $this->createQueryBuilder('m')
    ->where('m.from = ?1 or m.to = ?1')
    ->groupBy('m.key')
    ->orderBy('m.date', 'DESC')
    ->setParameter(1, $user->getId())
    ->setMaxResults($pagination) // limit
    ->setFirstResult($pagination * $page) // offset
;

return $qb->getQuery()->getResult();
16
Eddy

dans le cas où vous avez plusieurs colonnes dans 'group by', vous devez utiliser la méthode addGroupBy ().

$qb = $this->createQueryBuilder('m')
    ->where('m.from = ?1 or m.to = ?1')
    ->groupBy('m.to')
    ->addGroupBy('m.from')
    ->orderBy('m.date', 'DESC')
    ->setParameter(1, $user->getId())
    ->setMaxResults($pagination) // limit
    ->setFirstResult($pagination * $page) // offset
;

:)

4
Artur R.

Essayez ce qui suit en utilisant la méthode doctrine DQL - 

$query = $em->createQuery("SELECT m.id, m.from_id as c, m.to_id as c FROM AcmeDemoBunlde:Message as m WHERE m.c = 1 GROUP BY m.from_id, m.to_id"); 

$messageDetails = $query->getResult(); 

Au lieu de AcmeDemoBundle replace avec le nom de votre bundle approprié.

0