Подтвердить что ты не робот

Query Builder и Group By на двух столбцах в Symfony2/Doctrine генерируют дубликаты

Я создаю пакет сообщений, где сообщения группируются для контактов. На моей индексной странице отображаются разные потоки. Когда вы кликаете по одному потоку, он показывает все сообщения, обменянные между вами и вашим контактом. Я использую Query Builder для отображения потоков на моей индексной странице:

$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
;

Если у меня есть 3 записи, например:

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

Я ожидаю:

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

Но я получаю:

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

Я нашел способ сделать это с помощью SQL, используя тот же псевдоним для from_id и to_id:

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

Но я не знаю, как это сделать с Доктриной.

EDIT:

Пока я не получу лучшую идею, я использую ключ, чтобы легко "группировать".

// 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();
4b9b3361

Ответ 1

если у вас много столбцов в группе, вы должны использовать метод 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
;

:)

Ответ 2

Попробуйте следующее с помощью метода доктрины 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(); 

Вместо AcmeDemoBundle замените нужное имя пакета.