2017-06-14 1 views
2

J'ai besoin d'aide pour queryBuilder en doctrine.symfony - doctrine - Récupérer toutes les données de mon bdd sauf quelques unes

Je recherche un queryBuilderMethod pour, obtenir toutes les données sauf quelques-unes.

par exemple dans sql avec une table ses quelque chose comme ceci:

"select * from table Where user != "a" && user != "b" && user != c [...]" 

i have 3 entité dans mes applications symfony:

utilisateur => un à plusieurs => Photo => un à many => RatingsPhoto

Je veux obtenir un utilisateur qui n'a pas encore évalué par l'utilisateur actuel.

le code ci-dessous:

utilisateur

class User extends BaseUser 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 
    /** @ORM\Column(name="facebook_id", type="string", length=255, nullable=true) */ 
    protected $facebook_id; 
    /** @ORM\Column(name="facebook_access_token", type="string", length=255, nullable=true) */ 
    protected $facebook_access_token; 
/** @ORM\Column(name="sex_target", type="integer", nullable=true) */ 
protected $sex_target; 
/** @ORM\Column(name="sex", type="integer", nullable=true) */ 
protected $sex; 

/** 
* @ORM\OneToMany(targetEntity="Photo", mappedBy="user") 
*/ 
protected $photo; 

/** 
* @ORM\OneToMany(targetEntity="RatingsPhoto", mappedBy="userMap", 
* cascade={"persist", "remove"}) 
*/ 
protected $ratingsUser; 

public function __construct() 
{ 
    $this->photo = new ArrayCollection(); 
    $this->ratingsUser = new ArrayCollection(); 
} 

}

photo

class Photo 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="User") 
    * @ORM\JoinColumn(name="user", referencedColumnName="id", nullable=false) 
    */ 
    protected $user; 

/** 
* @ORM\OneToMany(targetEntity="RatingsPhoto", mappedBy="photoMap", 
* cascade={"persist", "remove"}) 
*/ 
protected $ratingsPhoto; 

/** 
* @var int 
* 
* @ORM\Column(name="numeroPlayer", type="integer", nullable=true) 
*/ 
protected $numeroPlayer; 

/** 
* @var int 
* 
* @ORM\Column(name="nbrChoosen", type="integer", nullable=true) 
*/ 
protected $nbrChoosen; 

/** 
* @var string 
* 
* @ORM\Column(name="photoName", type="string", length=255, unique=true, nullable=false) 
*/ 
protected $photoName; 

/** 
* @ORM\Column(type="string", length=255, nullable=false) 
* @var string 
*/ 
protected $image; 

/** 
* @var \DateTime 
* 
* @ORM\Column(name="dateAdd", type="datetime") 
*/ 
protected $dateAdd; 
/** 
* Constructor 
*/ 
public function __construct() 
{ 
    $this->ratingsPhoto = new ArrayCollection(); 
} 

}

RatingsPhoto

classe RatingsPhoto {

public function __construct() 
{ 

} 

/** 
* @var int 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 

/** 
* @ORM\ManyToOne(targetEntity="User", inversedBy="ratingsUser") 
* @ORM\JoinColumn(name="user", referencedColumnName="id", nullable=false, onDelete="CASCADE") 
*/ 
protected $userMap; 

/** 
* @ORM\ManyToOne(targetEntity="Photo", inversedBy="ratingsPhoto") 
* @ORM\JoinColumn(name="photo", referencedColumnName="id", nullable=false, onDelete="CASCADE") 
*/ 
protected $photoMap; 

/** 
* @var int 
* 
* @ORM\Column(name="note", type="integer", nullable=false) 
*/ 
protected $note; 

/** 
* @var \DateTime 
* 
* @ORM\Column(name="dateNote", type="datetime", nullable=false) 
*/ 
protected $dateNote; 

Requête requête que j'ai essayer, mais le travail doesent

$result = $this->getEntityManager() 
->createQuery(
    'SELECT p, u, r 
    FROM AppBundle:Photo p 
    LEFT JOIN p.user u 
    LEFT JOIN p.RatingsPhoto r 
    WHERE u != :user 
    AND r.user != :user 
    AND u.sex = :sex 
    order By Rand()' 
) 
->setParameters(array('user' => $user, 'sex' => $user 
->getSexTarget())) 
->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY); 
+1

vous ne vous attendez pas à ce que nous fassions tout le travail ou? Comment la méthode de création de requête que vous avez essayée ressemble-t-elle? – lordrhodos

+0

non bien sûr: p, je recherche juste la méthode la plus optimisée et en une requête, je peux le faire avec 2 ou 3 requêtes et une boucle je suppose mais ce n'est pas optimisé. –

+0

j'ai essayé quelque chose comme ceci: –

Répondre

1

Juste pour clarifier les choses un peu d'abord.Ce n'est pas 100% correct:

utilisateur => un à plusieurs => Photo => un à plusieurs => RatingsPhoto

Qu'est-ce que vous avez il y a un classique Many-to-many relation avec attributs supplémentaires, Wich n'est pas h: n relation plus, mais présente votre entité relationnelle dédiée RatingsPhoto

donc ce que vous avez en gros est

utilisation r < OneToMany>RatingsPhoto < ManyToOne>photo

En plus de chaque utilisateur peut avoir plusieurs photos, ce qui est une sorte d'une propriété pour photo

utilisateur < OneToMany>Photo

D'abord une petite suggestion, renommer le Utilisateur: photo attribuer à Utilisateur: photos afin qu'il reflète la relation correcte.

/** 
* @ORM\OneToMany(targetEntity="Photo", mappedBy="user") 
*/ 
protected $photos; 

En ce qui concerne votre requête:

Je veux obtenir un utilisateur qui n'a pas encore évalué par l'utilisateur courant.

vous devez construire votre requête à l'aide d'un sous-requête, comme get all users that are not in (a list of users which photos have been rated by the current user):

Vous pouvez essayer quelque chose comme ça (non testé):

$result = $this->getEntityManager() 
    ->createQuery(
     'SELECT u 
     FROM AppBundle:User u 
     WHERE u.id not in 
      (
       SELECT ru.i FROM AppBundle:RatingsPhoto r 
       LEFT JOIN u.photos p, 
       LEFT JOIN p.user ru 
       WHERE r.userMap = :user 
      ) 
     AND u.sex = :sex 
     order By Rand()' 
    ) 
    ->setParameters(array('user' => $user, 'sex' => $user 
    ->getSexTarget())) 
    ->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY); 
+0

Merci beaucoup! votre réponse a beaucoup de m'aider! J'ai trouvé quelque chose de similaire que je publie ci-dessous. –

1

Enfin j'ai trouvé la réponse, je mets le code ci-dessous si qui peut aider quelqu'un:

$result = $queryBuilder 
    ->select(['p, ru, u']) 
    ->from('AppBundle:Photo', 'p') 
    ->leftJoin('p.ratingsPhoto', 'ru') 
    ->leftJoin('p.user', 'u') 
    ->where('ru.id IS NULL') 
    ->Orwhere($queryBuilder->expr()->not($queryBuilder->expr()->exists(' 
      SELECT sr.id 
      FROM AppBundle:RatingsPhoto sr 
      WHERE sr.userMap = :user' 
    ))) 
    ->andWhere('u.sex = :sex') 
    ->setParameters(array('user' => $user, 'sex' => $user->getSexTarget())) 
    ->getQuery() 
    ->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY) 
;