2017-01-12 2 views
0

Предполагая следующие две таблицы: «пользователь» и «друзья»;Doctrine 2 QueryBuilder

'user' 
column: id 
column: name 

'friends' 
column: user_id 
column: user2_id 

Обе колонки в таблице друзей соответствуют столбцу идентификатора таблицы пользователя.

Теперь я могу просто найти пользователей путем частичного имени со следующим:

$query='jim'; 
$result=$em->getRepository('\User\Entity\User') 
     ->createQueryBuilder('u') 
     ->where('u.name like :match') 
     ->setParameter('match', $query.'%') 
     ->setMaxResults(5) 
     ->getQuery() 
     ->getResult(); 

Теперь предполагая объект \ User \ Entity \ User ПользовательА, как бы я сделать частичное совпадение строки для всех пользователей, которые ПользовательА является не друзей с уже?

EDITДобавлен Entity определения

/** 
* User 
* 
* @ORM\Table(name="user", uniqueConstraints={@ORM\UniqueConstraint(name="name_key", columns={"name"})}) 
* @ORM\Entity 
*/ 
class User 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="bigint", precision=0, scale=0, nullable=false, unique=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255, precision=0, scale=0, nullable=false, unique=false) 
    */ 
    private $name; 
} 


/** 
* UserFriends 
* 
* @ORM\Table(name="user_friends", indexes={@ORM\Index(name="user_id_key", columns={"user_id"}), @ORM\Index(name="friend_user_id_key", columns={"friend_user_id"})}) 
* @ORM\Entity 
*/ 
class UserFriends 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="bigint", precision=0, scale=0, nullable=false, unique=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var \User\Entity\User 
    * 
    * @ORM\ManyToOne(targetEntity="User\Entity\User") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="friend_user_id", referencedColumnName="id", nullable=true) 
    * }) 
    */ 
    private $friendUser; 

    /** 
    * @var \User\Entity\User 
    * 
    * @ORM\ManyToOne(targetEntity="User\Entity\User") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true) 
    * }) 
    */ 
    private $user; 
}` 
+0

Вместо столбцов таблицы, пожалуйста, разместите определения сущности? – lxg

ответ

0

Мы сделаем это в два этапа. Во-первых, мы узнаем, с какими пользователями они являются друзьями, затем мы делаем запрос, исключая их.

Во-первых, мы получаем список ID друзей пользователя:

$friendIds = $em->createQuery(" 
    SELECT IDENTITY(uf.user) 
    FROM User\Entity\UserFriends uf 
    WHERE uf.user = :id") 
->setParameter("id", $userId) // $userId is the ID of the target user 
->getResult(); 

$friendIds = array_map("current", $friendIds); // needed for flattening the array 

Теперь мы просто запросить таблицу пользователей, за исключением идентификаторов наших друзей:

$notMyFriends = $em->createQuery(" 
    SELECT u 
    FROM User\Entity\User u 
    WHERE u.id != :ownid 
    AND WHERE u.id NOT IN (:friends)") 
->setParameter("ownid", $userId) // $userId is the ID of the target user 
->setParameter("friends", $friendIds) 
->getResult(); 

Я использую обычный DQL, но если вы предпочитаете построитель запросов, вы также можете переписать его в цепочку методов QB.

(Все вышеперечисленное из верхней части моей головы, надеюсь, что это работает. Если нет, пожалуйста, оставьте комментарий, и я постараюсь это исправить.)


Кстати, пожалуйста позвольте мне дать вам несколько советов относительно классов сущностей:

  • классы сущностей всегда должны быть в единственном числе UserFriendsUserFriend.

  • все ваши аннотации параметров являются излишними, так как Doctrine автоматически укажет ваши таблицы, индексы и столбцы.

  • То же самое касается JoinColumns ... вы можете полностью их опустить, если вы не хотите явно изменять поведение по умолчанию (чего обычно нет).

  • nullable=true по умолчанию для отношения xToOne, поэтому его также можно опустить.

  • nullable=false и unique=false не имеют смысла на поле идентификатора. Первое является избыточным, второе невозможно.

+0

Привет, я дам ему попробовать и отчитаться. Что касается других предложений, объекты были автоматически сгенерированы доктриной из таблиц базы данных. – Moe

+0

Ваше решение сработало, спасибо вам, сэр! – Moe

+0

Рад, что я мог помочь. Работало ли это так, или вы изменили мой код? Если это так, пожалуйста, обновите мой ответ своими исправлениями, чтобы следующий парень тоже мог воспользоваться этим. – lxg

Смежные вопросы