Collection et compteur

gestion avancé

Le problème exposé dans ce sujet a été résolu.

Bonjour, j'ai une entité qui possède un compteur de visites, qui est une collection doctrine. Jusque là tous vas bien. J'aimerais pourvoir récupérer le nombre de visite unique. Je trouve aucun moyen de faire dans mon entité parant un group by sur l'id du visiteur quand je récupérer ma collection.

Qui a une technique ou une astuces ? ( j'arrive à récupérer les infos, mais j'ai 90 requêtes pour 10 contenues je veux réduire ça)

+0 -0

Salut !

J'aimerais juste comprendre comment tu arrives à 90 requête pour 10 contenus, tu pourrais me l'expliquer ?

Pour ton problème, voici la solution que je te proposerais :

Créer une méthode dans ton ContenuRepository qui, à l'aide d'une jointure et d'un dinstinct() bien placé te retourne les entités Contenu avec une collection de Visite dont aucune n'a le même visiteur qu'une autre dans la collection, ceci permettant d'utiliser {{ contenu.visites.count }}.
Avantages : le "filtrage" est fait par la base de données (rapide) ; on manipule un minimum d'information
Désavantage : pas adapté au cas où il faut en plus afficher toutes les visites sans distinction en plus des visites uniques

+0 -0

Salut !

J'aimerais juste comprendre comment tu arrives à 90 requête pour 10 contenus, tu pourrais me l'expliquer ?

Pour ton problème, voici la solution que je te proposerais :

Créer une méthode dans ton ContenuRepository qui, à l'aide d'une jointure et d'un dinstinct() bien placé te retourne les entités Contenu avec une collection de Visite dont aucune n'a le même visiteur qu'une autre dans la collection, ceci permettant d'utiliser {{ contenu.visites.count }}. Avantages : le "filtrage" est fait par la base de données (rapide) ; on manipule un minimum d'information
Désavantage : pas adapté au cas où il faut en plus afficher toutes les visites sans distinction en plus des visites uniques

Ymox

Car j'ai plein d'autre fonctionnalités et donc plein d'autre requête générer. Ta méthode parais bien mais comment je dois appeler cette méthode pour qu'elle soit appeler par le setteur ?

+0 -0

Je pense que le mieux pour qu'on puisse t'aider, c'est que tu nous parles de toutes les entités qui sont impliquées.

Je t'avoue ne pas comprendre ce que viendrait faire un setteur là-dedans ? On va récupérer des informations selon certains critères, on n'en créé ni n'en modifie, il me semble ?

+0 -0

Euh des fois je me pose des questions…

Je sais pas toi mais quand je veux récupérer une collection je fais

1
$entity->getEntities();

qui lui va appeler la bon setteur pour hydrater la collections. Je peux bien écrire une fonction dans mon repositroy mais si elle n'est pas appeler elle sert à rien. Ya pas besoin de code là dedans. Pour m'expliquer la procédure à suivre. Ps: je me suis peut être mal exprimé.

+0 -0

Dans ce cas, je pense que tu voulais dire "getteur", non ?  ;)

Avec la méthode que je te propose, ça ne changera absolument rien : on ne fait que modifier les informations qui seront dans les objets, pas leur organisation (relations) entre eux.

+0 -0

ça d'accord, c'est bien ce que je recherche. Mais quand je fais un

1
entity->getEntities() 

Symfony fait appele au respository liée à entities ? qui va appeler une fonction qui va réaliser la requête.

Ma question reviens à : Comment s'appelle cette fonction ou Comment je dis à doctrine utilise cette fonction ? Théoriquement pas de problèmes, c'est juste la pratique qui me cause soucis !

+0 -0

D'accord.

Alors tu ne dis pas à Doctrine d'utiliser des fonctions de ton repository, c'est à toi de les appeler. Tout comme tu utilises find() et/ou findBy(), tu peux te créer ta propre méthode et l'utiliser.

+0 -0

ok, pas moyen d'être plus fin ? Parce que j'aimerais bien que cette appelé soit indépendant.

Actuellement je par d'une entité Actus qui possédé une entité réponse et une entité content qui possédé l'entité counter.

donc ma fonction findBy fais à partir d'actus :

1
2
3
4
->leftjoint(réponse, r)
->leftjoint(content, c)
->addSelect(r)
->addSelect(c)

Je suis pratiquement sur que si je rajoute :

1
->groupBy(c.user)

(puisque que je veux les visite unique par utilisateur - qui est forcement enregistrer - ) que ça va faire un joli boxons.

Je vais retenter par acquis de conscience.

+0 -0

c'est bien ce que je pensais si je vous le group by il me retourne deux résultats !

Pour récupérer dans le gros pas de soucis mais dés qu'on veux dans le détail :/

+0 -0
1
2
3
4
5
6
7
8
SELECT *
FROM actus n0_ 
LEFT JOIN content c1_ ON n0_.content_id = c1_.id LEFT JOIN reply r2_ ON n0_.id = r2_.actu_id 
LEFT JOIN users u3_ ON n0_.user_id = u3_.id LEFT JOIN category w4_ ON n0_.category _id = w4_.id 
LEFT JOIN counter c5_ ON c1_.id = c5_.content_id 
WHERE n0_.id IN (5122, 5121, 5120, 5116, 5115, 5114, 5101, 5106, 5057, 5055) 
GROUP BY c5_.user_id 
ORDER BY n0_.modification DESC, r2_.date ASC
+0 -0

En fait, il ne faut pas regrouper que par ID d'utilisateur, mais aussi et avant par ID d'actu (n0_.id), sinon tu vas juste savoir quel utilisateur a regardé du contenu, ce qui n'est pas vraiment ton but, parce qu'il te manquera l'information quel contenu.

+0 -0

oui j'ai tester et ça fout le bordelle !

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
->leftjoin('a.content','c')
->addSelect('c')

->leftjoin('a.replies','r')
->addSelect('r')
->leftjoin('a.user','u')
->addSelect('u')
->leftjoin('a.category','w')
->addSelect('w')
// modif pour le group by
//->leftjoin('c.counters', 'cpt')
//->addSelect('cpt')
//->groupBy('a.id, cpt.user')
;

$i = 0;
foreach ($criteria as $key => $value) {
        $qb->andWhere('a.'.$key.' IN(:'.$key.')')->setParameter($key, $value);
}

if($orderBy != null){
    foreach ($orderBy as $key => $value) {
        $qb->orderBy('a.'.$key, $value);
    }
}
$qb->setMaxResults($limit)
   ->setFirstResult($offset);

voilà mon findBy

+0 -0

Je vais reprendre de ce que j'ai compris, et ce que je testerais.

1
2
3
4
5
6
7
8
9
<?php
$qb = $this->createQueryBuilder('a');
$qb ->select($qb->expr()->countDistinct('nb.user')) // Note que cela pourrait te permettre de te passer du groupBy nb.user
    ->leftjoin('a.replies','r')->addSelect('r')
    ->leftjoin('a.user','u')->addSelect('u')
    ->leftjoin('a.category','w')->addSelect('w')
    ->leftJoin('a.content', 'c')->addSelect('c')
    ->leftJoin('c.counters', 'nb')
    ->groupBy('c.id, nb.user')

A noter que la structure du résultat peut être un brin déroutante

+0 -0

Merci pour ton aide ! mais finalement on est partie dans une autre direction !

le résultat équivalent (on est passé à 22 requêtes sur les page en question - on attendais 30 ) et d'avoir créer un contrôle de requêtes ! on a récupérer les id contents pour faire une requête global sur les compteurs !

Avec une requête supplémentairement on a put économisé 10, etc …

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte