Nie robisz tego poprawnie, dopasowujesz etykiety i wartości do ostatnich wartości filtra, ponieważ symbole zastępcze :label
, :value
użyte w zapytaniu nie są unikalne dla każdej iteracji pętli, więc wszystkie klauzule generowane przez pętlę będą pasować do ostatniej etykiety i wartości.
Aby uzyskać oferty pracy, których każda właściwość pasuje do dostarczonych filtrów, możesz napisać podobnie jak poniżej zapytanie doktryny.
Najpierw zbierze wszystkie etykiety i wartości w osobnej tablicy, a następnie dopasuje się do właściwości zadania za pomocą IN()
operacja, w końcu, aby uzyskać zadania, których właściwości pasują do wszystkich filtrów potrzebnych do zbudowania agregacji, aby zliczyć pasujące wyniki i powinna być równa liczbie filtrów
$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();