Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Doctrine QueryBuilder:ManyToOne-Beziehung, bei der mehr als eine Unterentität übereinstimmen muss

Sie machen es nicht richtig, Sie gleichen Labels und Werte mit den letzten Filterwerten ab, weil die Platzhalter :label , :value die in der Abfrage verwendet werden, sind nicht für jede Schleifeniteration eindeutig, daher stimmen alle von der Schleife generierten Klauseln mit dem letzten Label und Wert überein.

Um die Jobs zu erhalten, deren Eigenschaften mit den bereitgestellten Filtern übereinstimmen, können Sie etwas wie die folgende Doktrinenabfrage schreiben.

Zuerst werden alle Labels und Werte in einem separaten Array gesammelt und dann mit IN() mit den Eigenschaften des Jobs abgeglichen Operation, um zuletzt die Jobs zu erhalten, deren Eigenschaften mit allen Filtern übereinstimmen, die Sie benötigen, um eine Aggregation zu erstellen, um die übereinstimmenden Ergebnisse zu zählen, und sollte gleich der Anzahl der Filter sein

$qb =  $this->getDoctrine()
            ->getRepository('AppBundle:Job')
            ->createQueryBuilder('job')
            ->innerJoin('job.properties','p');
$labels = array();
$values = array();
foreach($filters as $label => $value)
{
    $labels[] = $label;
    $values[] = $value;
}
$qb->addSelect('COUNT(DISTINCT  p.id) AS total_properties')
   ->andWhere('p.label IN (:labels)')
   ->andWhere('p.value IN (:values)')
   ->addGroupBy('job.id')
   ->having('total_properties = '.count($filters))
   ->setParameter('labels',$labels)
   ->setParameter('values',$values)
   ->getQuery()
   ->getResult();