IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

QueryBuilder ManyToMany avec WHERE IN [2.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Par défaut QueryBuilder ManyToMany avec WHERE IN
    Bonjour a tous,

    J'ai un soucis sur un moteur de recherche produits sur lequel je ne comprends vraiment plus rien et je souhaiterai avoir un peu de vos lumières.

    Mon site comprend une entité centrale (produit), a laquelle sont rattachés de nombreux éléments (categories, marques, avis, photos...), bref beaucoup de choses... J'ai un moteur de recherche permettant de trouver un produit par le biais de critères ou tout se passe bien sauf quand je veux trier par catégories.

    Je m'explique: je veux rendre possible le fait de filtrer les produits en y affichant ceux qui font partis de categories que l'utilisateur aura choisi et ce dans la logique suivante:
    - le moteur ne doit retourner que les produits qui font partis de TOUTES les catégories choisies
    - le moteur peut afficher des produits qui sont attachés a d'autres catégories tant que l'on respecte la première règle

    Actuellement le systême fonctionne presque mais semble retourner tous les produits qui font parti d'au moins une des catégories selectionnées mais cela ne respecte pas ma première règle.

    Je pense que mon problème vient de ma facon d'utiliser WHERE IN mais je n'arrive vraiment plus a comprendre. A noter que la relation entre les categories et les produits est ManyToMany.

    Voici comment je fais mon tri:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    28
    29
    30
     
    public function searchProduits($request, $page, $perPage, $type = null){
        $query = $this->createQueryBuilder('p')
            ->leftJoin('p.avis','a')
            ->leftJoin('a.user','u')
            ->leftJoin('p.marque','m')
            ->leftJoin('p.categories','s')
            ->leftJoin('s.categorie', 'c')
            ->leftJoin('p.type','t')
            ->addSelect('a')
            ->addSelect('m')
            ->addSelect('s')
            ->addSelect('c')
            ->addSelect('u')
            ->addSelect('t')
            ->where('p.active = true')
            ->groupBy('p');
     
        $categories = array();
        foreach($request["categories"] as $cat){
            //$query->add('where', $query->expr()->in('s.id', $cat->getId()));
            // $query->andWhere($query->expr()->in('s.id',$cat->getId()));
            $categories[] = $cat->getId();
        }
     
        if(count($categories) > 0){
            $query->andWhere('s.id IN(:cats)')->setParameter('cats', $categories);
        }
     
    // suite des tri (par marque / par nb d'avis a la suite du script mais fonctionnel jusque la)
    Comme vous pouvez le voir j'ai fais plusieurs tests (dont j'ai laissé les lignes en commentaires), mais rien ne fonctionne comme je le voudrai, d'où pourrait venir mon problème?

    Merci d'avance pour votre aide.

  2. #2
    Membre Expert
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 419
    Par défaut
    Problème intéressant, plus proche du SQL je pense. A mon avis tu trouverai une meilleure réponse la bas en travaillant d'abord sur la requete brute, pour l'adapter ensuite sur doctrine.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT *
    FROM Produit p
    JOIN Produit_Categorie pc ON p.id = pc.produit_id
    JOIN Categorie c1 WHERE pc.categorie_id = c1.id
    JOIN Categorie c2 WHERE pc.categorie_id = c2.id
    JOIN Categorie c3 WHERE pc.categorie_id = c3.id
    JOIN Categorie c4 WHERE pc.categorie_id = c4.id
    JOIN Categorie c5 WHERE pc.categorie_id = c5.id
    JOIN Categorie c6 WHERE pc.categorie_id = c6.id
    Quelque chose comme ca devrait fonctionner.

    Ou alors, il faudra peut etre multiplier le join sur produit_Categorie aussi...

    Pour moi, cette requête devrait te permettre de retourner tous les produits qui ont une jointure avec la bonne catégorie.

    Les autres join importe peu.

    Par contre, tu ne devrait pas avoir de leftjoin dans ta requete... bien moins efficace et je doute que tu puisses avoir un avis sur un utilisateur NULL... ce qui est pourtant l'avantage d'un LEFT JOIN.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Par défaut
    C'est dans ces moments que je me dis que SQL est vraiment très puissant mais demande une grosse maitrise pour arriver a faire des tris poussés comme ceux là!

    J'ai essayé de tenir compte de cette remarque et de repartir sur du SQL brute avant d'utiliser le queryBuilder, et effectivement ca marche! du coup sur le code je l'ai répercuté comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        $categories = array();
        foreach($request["categories"] as $key=>$cat){
            $query->join('p.categories','s'.$key);
            $query->andWhere('s'.$key.' = '.$cat->getId());
        }
    Merci beaucoup pour le coup de main!

  4. #4
    Membre Expert
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 419
    Par défaut
    Juste une remarque, le nombre de max de join est souvent élevé maintenant, mais a raison de 2 join par catégorie, il vaut quand même mieux que tu n'en ai pas 100 à faire. Cette méthode fonctionnera très bien pour 5-10 éléments max, mais je pense qu'il faudra réfléchir a autre chose si tu va vers des nombre de catégorie élevés.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme update avec where sur requete imbriqué
    Par JulienCEA dans le forum Requêtes
    Réponses: 11
    Dernier message: 04/06/2008, 11h44
  2. Réponses: 5
    Dernier message: 10/07/2006, 12h05
  3. [MySQL] INNER & OUTER JOIN imbriqués avec WHERE
    Par kelson dans le forum Langage SQL
    Réponses: 1
    Dernier message: 28/02/2006, 12h00
  4. probleme avec WHERE ... BETWEEN ... AND ...
    Par toyyo dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 30/11/2005, 14h25
  5. Probleme requete Mysql avec WHERE
    Par Dom_the_quaker dans le forum Requêtes
    Réponses: 3
    Dernier message: 24/10/2005, 16h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo