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);
Author: Arthur Crosnier, 2017-06-14

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);
 1
Author: lordrhodos, 2017-06-14 19:12:55

Наконец-то я нашел ответ, я поместил код ниже, если это может кому-то помочь:

$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)
;
 1
Author: Arthur Crosnier, 2017-06-15 13:33:48