Doctrine 2 agregační funkce

Iva Phamová
Člen | 6
+
0
-

Přeji hezký den, mohla bych se prosím váš zeptat, proč mi blbne následující dotaz?

return $this->em->createQuery('
    SELECT  COUNT(u.id) AS pocet, u, PARTIAL b.{id, reason}
    FROM App\Model\Entities\User u
    INNER JOIN u.ban b
    WHERE u.username LIKE :name
')
			->setFirstResult(0)
    ->setParameter('name', "%{$username}%")
    ->setMaxResults(5)
    ->getResult();

nemělo by getResult vrátit pole objektů? Zadala jsem takové vstupy, aby to opravdu našlo více objektů. Ale místo toho mi to vrátí.

array (1)
	0 => array (2)
		0 => App\Model\Entities\User #5c06
			id => 23
			username => "anna" (8)
			password => ...
			email => ...
			role => admin
			ip => ::1
			ban => App\Model\Entities\Ban #f58b { ... }
			settings => App\Model\Entities\UserSettings #b4da { ... }
			articles => Doctrine\ORM\PersistentCollection #f7f1 { ... }
		pocet => "4"

Nevíte, jak je to možné? Potřebovala bych to totiž projet foreach cyklem a nejde to, když to nevrací to pole objektů.
V dokumentaci stojí:

$users = $query->getResult(); // array of ForumUser objects

Pokud víte, tak budu moc ráda, když mi pomůžete.

Editoval Iva Phamová (5. 8. 2017 19:48)

ZahorskyJan
Člen | 55
+
0
-

@IvaPhamová ten vysledek je vzhledem k uvedene SELECT casti spravne. Count, jako agregacni funkce, nejdriv seskupi, spocita (v tomhle pripade pocet vyskytu) a vrati vysledek. To seskupeni ale ovlivnuje cely dotaz, takze kvuli tomu to vrati jenom jeden zaznam, vicemene nahodny. Kdyz ten stejny dotaz polozis primo do databaze, bude vysledkem take jenom jeden zaznam. Ovlivnit se to da pomoci GROUP BY, ktere by ve vhodne kombinaci mohlo pocitat vyskyty v join tabulce treba. Zalezi, co ma byt vysledkem.

Ohledne Doctrine a toho, ze vraci vicerozmerne pole, tak je to z toho duvodu, ze nevi, kam ten COUNT(u.id) AS pocet ma do objektu (entity User) dat, protoze zadna takova property tam neni. V takovem pripade vraci jako vysledek jednoho radku pole: entity, ktere umi poskladat a ty casti SELECTu, ktere jsou tam dal uvedene a nikam nepatri nebo v entitni siti nemaji uvedenou vazbu.

Nevim co ma byt vysledkem, ale myslim, ze by SELECT cast mela vypadat nejspis jenom takhle: SELECT u, b

Partial bych vynechal a uvedl bych celou entitu Ban, resp. b., at je k dispozici cela. Vysledek pak bude pole entit (objektu). A diky uvedeni entity ban v select zajistis, ze pri praci s ni uz doctrina nepolozi dalsi dotaz, ale uz ji ma nactenou.

Pokud jsi ten pocet zaznamu z count chtela vedet kvuli strankovani, napovidal by tomu ten setMaxResult, tak na to se pouziva primo Paginator trida z Doctriny, viz dokumentace Doctrine

Editoval ZahorskyJan (6. 8. 2017 9:13)

Zuben45
Člen | 268
+
0
-

Jak píše @ZahorskyJan neexistuje property, také jsem měl podobný problém, a řešení je jednoduché, stačí použít HIDDEN

return $this->em->createQuery('
    SELECT  COUNT(u.id) AS HIDDEN pocet, u, PARTIAL b.{id, reason}
    FROM App\Model\Entities\User u
    INNER JOIN u.ban b
    WHERE u.username LIKE :name
')
    ->setFirstResult(0)
    ->setParameter('name', "%{$username}%")
    ->setMaxResults(5)
    ->getResult();