symfony - доктрина - Восстановите все данные моего bdd, кроме нескольких
Мне нужна помощь для QueryBuilder в доктрине.
Я ищу метод построения запросов, получаю все данные, кроме нескольких.
Например, в sql с одной таблицей это примерно так:
"select * from table Where user != "a" && user != "b" && user != c [...]"
У меня есть 3 сущности в моих приложениях symfony:
Пользователь => один ко многим => Фото => один ко многим => Рейтинг фото
Я хочу получить пользователя, который еще не получил оценку текущего пользователя.
Код ниже:
Пользователь
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();
}
}
Рейтингфото
Рейтинг классовфото {
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;
Запрос запроса у меня есть попытка, но не работает
$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);
2 answers
Просто для начала немного проясню ситуацию. Это не на 100% правильно:
Пользователь => один ко многим => Фото => один ко многим => Рейтинг фото
То, что у вас есть, - это классическое отношение "многие ко многим" с дополнительными атрибутами, которое больше не является отношением m:n, но представляет вашу выделенную реляционную сущность Рейтингфото
Итак, что у вас в основном есть, это
Пользователь оНетОмАния> Рейтингфото Многотонный> Фотография
Кроме того, у каждого пользователя может быть несколько фотографий, что является своего рода правом собственности на Фотографию
Пользователь оНетОмАния> Фотография
Сначала небольшое предложение, переименуйте атрибут Пользователь:фотография в атрибут Пользователь: фотографии, чтобы он отражал правильное отношение.
/**
* @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);
Наконец-то я нашел ответ, я поместил код ниже, если это может кому-то помочь:
$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)
;