2017-01-12 10 views
0

'user'と 'friends'の2つのテーブルを仮定します。Doctrine 2 QueryBuilder

'user' 
column: id 
column: name 

'friends' 
column: user_id 
column: user2_id 

友人テーブルの両方の列は、ユーザーテーブルIDの列に対応します。

ここでは、次のように部分名でユーザーを検索することができます。今\ユーザー\エンティティ\ユーザーユーザAのオブジェクトを想定し

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

は、どのように私は、ユーザAが既に持つない友人であるすべてのユーザーのための部分的な文字列の一致をしますか?

EDIT追加エンティティ定義

/** 
* 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 

今、私たちは、単に私たちの友人のIDを除く、ユーザーテーブルをクエリ:

$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メソッドチェーンに書き直すこともできます。

(上記のすべては、私の頭の上からで、それが動作を期待しています。ない場合は、コメントを残して、私はそれを修正しようとするでしょうしてください。)


ところで、してください私はあなたのエンティティクラスに関するいくつかのヒントを与えてみましょう:

  • エンティティクラスは常に→UserFriend単数UserFriendsにする必要があります。

  • すべてのname="foobar"アノテーションパラメータは冗長です。Doctrineはテーブル、インデックス、カラムを自動的に名前付けします。

  • 同じことは、デフォルトの動作(明示的には変更しない)を明示的に変更しない限り、すべて省略することができます。

  • nullable=trueは、xToOneリレーションのデフォルトですので、省略することもできます。

  • nullable=falseおよびunique=falseは、IDフィールドでは意味をなさない。最初は冗長で、2番目は不可能です。

+0

乾杯、私はそれを試して報告して戻ってきます。他の提案に関して、エンティティはデータベーステーブルから教義によって自動生成されました。 – Moe

+0

あなたのソリューションはうまくいきました、ありがとうございました! – Moe

+0

うれしい私は助けることができます。これはちょうどこのように動作しましたか、または自分のコードを変更しましたか?もしそうなら、あなたの修正で私の答えを更新してください。そうすれば次の人にも恩恵を受けることができます。 – lxg

関連する問題