Wie wähle ich eine bestimmte Abfrage mit dem Symfony2 Doctrine Query Builder aus?

74

Ich habe diesen Symfony-Code, in dem alle Kategorien abgerufen werden, die sich auf einen Blog-Abschnitt in meinem Projekt beziehen:

$category = $catrep->createQueryBuilder('cc')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->getQuery();

$categories = $category->getResult();

Dies funktioniert, aber die Abfrage enthält Duplikate:

Test Content
Business
Test Content

Ich möchte den DISTINCTBefehl in meiner Abfrage verwenden. Die einzigen Beispiele, die ich gesehen habe, erfordern, dass ich unformatiertes SQL schreibe. Ich möchte dies so weit wie möglich vermeiden, da ich versuche, meinen gesamten Code gleich zu halten, damit alle die von Symfony2 / Doctrine bereitgestellte QueryBuilder-Funktion verwenden.

Ich habe versucht distinct(), meiner Abfrage Folgendes hinzuzufügen :

$category = $catrep->createQueryBuilder('cc')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->distinct('cc.categoryid')
    ->getQuery();

$categories = $category->getResult();

Dies führt jedoch zu folgendem Fehler:

Schwerwiegender Fehler: Aufruf der undefinierten Methode Doctrine \ ORM \ QueryBuilder :: unique ()

Wie sage ich Symfony, dass sie eine bestimmte auswählen soll?

mickburkejnr
quelle
2
Sie sollten einen booleschen Wert an die Funktion different () übergeben. doi-project.org/api/orm/2.2/…
Omn

Antworten:

31

du könntest schreiben

select DISTINCT f from t;

wie

select f from t group by f;

Die Sache ist, dass ich gerade selbst in die Lehre einsteige, also kann ich Ihnen keine wirkliche Antwort geben. Aber Sie können, wie oben gezeigt, eine eindeutige Gruppe mit simulieren und diese in Doktrin umwandeln . Wenn Sie weitere Filter hinzufügen möchten, verwenden Sie HAVINGnach Gruppieren nach.

Raffael
quelle
1
@mickburkejnr Bis Sie eine ORDER-Klausel hinzufügen. :(
undefiniert
1
@xyu Ich weiß, es ist nicht ideal, oder? Warum sollten wir mit so etwas schwerfällig sein? Warum kann es nicht einfach funktionieren?
Mickburkejnr
1
@mickburkejnr Die Gruppierung erfolgt vor der Bestellung in SQL.
undefiniert
11
Dies ist nur dann die richtige Antwort, wenn Sie eine SQL-Anweisung und nicht den Query Builder verwenden. Dies sollte nicht als Antwort markiert werden. Die von @skler gegebene Lösung ist die richtige.
Tom T
2
(Alter Kommentar, ich weiß ...). @ Tom T: Eigentlich ist diese Antwort gültig. Anstatt zu versuchen, das eigentliche DISTINCT Schlüsselwort zu verwenden, simulieren Sie es mithilfe von GROUP BYQueryBuilder. Er gab jedoch kein Beispiel. Hier ist eine einfache:$q = $db->createQueryBuilder(); $q->select('f')->from('t', 't')->groupBy('f');
user128216
170

Das funktioniert:

$category = $catrep->createQueryBuilder('cc')
        ->select('cc.categoryid')
        ->where('cc.contenttype = :type')
        ->setParameter('type', 'blogarticle')
        ->distinct()
        ->getQuery();

$categories = $category->getResult();
Skler
quelle
54

Wenn Sie die Anweisung "select ()" verwenden, können Sie Folgendes tun:

$category = $catrep->createQueryBuilder('cc')
    ->select('DISTINCT cc.contenttype')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->getQuery();

$categories = $category->getResult();
Chris
quelle
-1

Öffnen Sie einfach Ihre Repository-Datei, fügen Sie diese neue Funktion hinzu und rufen Sie sie in Ihrem Controller auf:

 public function distinctCategories(){
        return $this->createQueryBuilder('cc')
        ->where('cc.contenttype = :type')
        ->setParameter('type', 'blogarticle')
        ->groupBy('cc.blogarticle')
        ->getQuery()
        ->getResult()
        ;
    }

Dann in Ihrem Controller:

public function index(YourRepository $repo)
{
    $distinctCategories = $repo->distinctCategories();


    return $this->render('your_twig_file.html.twig', [
        'distinctCategories' => $distinctCategories
    ]);
}

Viel Glück!

Ali
quelle
Was meinst du mit "keiner hat funktioniert"? Was passiert stattdessen? Warum sollte das ein Problem von Symfony sein, während der Abfrage-Generator Teil von Doctrine ist?
Nico Haase
@NicoHaase, da beim Erstellen eines neuen Symfony-Projekts über Composer die neueste Version von Twig and Doctrine installiert wird, habe ich erwähnt, dass meine Lösung mit Symfony5 und der damit verbundenen Doctrine-Version getestet wird. Hoffe es ist jetzt klarer.
Ali