2017-06-14 24 views
2

我需要在教條中爲queryBuilder提供幫助。symfony - doctrine - 恢復除了幾個我的bdd的所有數據

我搜索一個queryBuilderMethod,獲取除少數幾個以外的所有數據。

例如在SQL中使用一個表的是這樣的:

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

我在我的symfony應用3單位:

用戶=>一對多=>照片=>之一許多=>評級照片

我想獲得尚未由當前用戶評分的用戶。

代碼如下:

用戶

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(); 
} 

}

照片

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

類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; 

請求查詢我有嘗試,但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

你不指望我們做所有的工作或?你試過的查詢生成器方法是怎樣的? – lordrhodos

+0

當然沒有:p,我只搜索最優化的方法,並且在一個請求中,我可以用2或3個請求和一個循環來做到這一點,但我認爲它沒有優化。 –

+0

我試過類似這樣的東西: –

回答

1

只是爲了首先澄清的東西一點點。這是不是100%正確:

用戶=>一對多=>照片=>一對多=> RatingsPhoto

你有什麼有一個經典的許多一對多與關係附加屬性,至極不是上午:N的關係了,而是引入了您的專用關係實體RatingsPhoto

那麼你基本上是

使用[R < 一對多>RatingsPhoto < 多對一>照片

更重要的是每個用戶可以擁有多張照片頂部,這是一種所有權爲照片

用戶 < OneToMany>圖片

首先小建議,重命名爲用戶:圖片屬性爲用戶:照片所以它反映了正確的關係。

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

關於您的查詢:

我想誰尚未被當前用戶額定的用戶。

你應該使用子查詢,像get all users that are not in (a list of users which photos have been rated by the current user)構建查詢:

你可以嘗試這樣的事情(未經測試):

$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

非常感謝!你的回覆有很多幫助我!我發現了一些類似的東西,我在下面發表。 –

1

終於讓我找到了答案,我把下面的代碼,如果可以幫助某人:

$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) 
;