我有一个用户实体和一个事件实体。用户可以通知他们想要参加一些活动。 这些用户也有自己的用户(自引用多对多关系)的朋友。何时使用innerJoin而不是使用Doctrine 2的地方?
我正在寻找从我的数据库中检索满足以下条件的用户朋友: 他们想要参加同一个活动。 他们彼此相邻。
虽然第二个条件很好,但我试图建立最佳查询,以确保第一个条件得到尊重。
这是我迄今所做的:不幸的是,我
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('USER', 'FRIENDS') // Selecting Me, the user who is asking to retrieve the users matched, and the friends who fill the criterias below
->from('Entity\User', 'USER') // we start with the user
->where('USER.id = :userId') // And I want the user the be me
->leftJoin('USER.friends', 'FRIENDS') // I'm going to take all of his friends
->innerJoin('FRIENDS.eventNotified', 'EVENT') //but ONLY the ones that have notified Events (array collection ov EVENT entity)
->leftJoin('EVENT.categories', 'c') //take events category in order to avoid doing any request when getting the name of the category
->leftJoin('EVENT.place', 'p') // same with the place where the event occured
->andWhere(
$qb->expr()->andX(
$qb->expr()->between('FRIENDS.latitude', ':minLat', ':maxLat'), //in a defined area
$qb->expr()->between('FRIENDS.longitude', ':minLng', ':maxLng'),
$qb->expr()->eq('FRIENDS.eventNotified.id', 'USER.eventNotified.id') //I want to select ONLY the friends who have notified they want to go to the same events than me (I have notified the same events as well)
)
)
->add('orderBy', $qb->expr()->sum('FRIENDS.latitude - :lat', 'FRIENDS.longitude - :lng'));
,这不是在做什么,我期待的事情。我想知道为什么。 因此,一旦我选择了朋友,我基本上只想选择已通知他们想要参加与我已通知的相同活动的朋友。
因此,我正在做一个innerJoin来检查朋友(他们是否是用户)已通知他们想要参加活动。然后在这些朋友中,我只想选择与我的$qb->expr()->eq('FRIENDS.eventNotified.id', 'USER.eventNotified.id')
相同的事件。
我认为这是我的问题...因为eventNotified是EVENT实体的集合,我只希望选择我们都通知的事件,我可以摆脱.id
?另外,我感觉这是选择所有的事件,当我只想检索我们在共同通知的事件时。所以我相信我应该在这里做一个内心的加入,但我可以找到合适的合成器。
有什么建议吗?
感谢
奖励:我应该还可以指定我想找回在SELECT语句中的“C”和“P”?
编辑:
我尝试了以下解决方案,但我得到这个错误,我不明白。我如何检索完整的错误信息? (部分缺失!)
码我曾尝试:
//我们只想要回附近的用户谁是可用的或者谁 $ QB = $这个 - > getEntityManager() - > createQueryBuilder() ;
$qb->select('USER', 'FRIENDS') // Selecting Me, the user who is asking to retrieve the users matched, and the friends who fill the criterias below
->from('Entity\User', 'USER') // we start with the user
->where('USER = :user') // And I want the user the be me
->leftJoin('USER.friends', 'FRIENDS', 'WITH', 'USER.eventNotified = FRIENDS.eventNotified');
$array = array(
'user' => $user
);
$qb->setParameters($array);
$usersMatched = $qb->getQuery()->getResult();
错误:
Fatal error: Uncaught exception 'Doctrine\ORM\Query\QueryException' with message 'SELECT USER, FRIENDS FROM Entity\User USER LEFT JOIN USER.friends FRIENDS WITH USER.eventNotified = FRIENDS.eventNotified WHERE USER = :user' in /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/QueryException.php:39Stack trace:#0 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(429): Doctrine\ORM\Query\QueryException::dqlError('SELECT USER, FR...')#1 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(686): Doctrine\ORM\Query\Parser->semanticalError('Invalid PathExp...', Array)#2 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(240): Doctrine\ORM\Query\Parser->_processDeferredPathExpressions(Object(Doctrine\ORM\Query\AST\SelectStatement))#3 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(304): Doctrine\ORM\Query\Parser->getAST()#4 /Users in /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/QueryException.php on line 49
看来,Doctrine2不喜欢'WITH', 'USER.eventNotified = FRIENDS.eventNotified'
出于某种原因。我不明白为什么。没有这一点代码,代码工作正常,但这种情况确实没有实现。
非常感谢您的帮助
EDIT2:
想什么在下面的答案的第三点意见,我仍然得到类似的错误消息后:
Fatal error: Uncaught exception 'Doctrine\ORM\Query\QueryException' with message 'SELECT USER, FRIENDS, EVENT, c, p FROM Entity\User USER LEFT JOIN USER.friends FRIENDS WHERE USER = :user AND USER.eventNotified = FRIENDS.eventNotified' in /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/QueryException.php:39Stack trace:#0 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(429): Doctrine\ORM\Query\QueryException::dqlError('SELECT USER, FR...')#1 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(528): Doctrine\ORM\Query\Parser->semanticalError(''EVENT' is not ...', Array)#2 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(233): Doctrine\ORM\Query\Parser->_processDeferredIdentificationVariables()#3 /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(304): Doctrine\ORM\Query\Parser->getAST()#4 /Users/YohannM/Sites/meetmyfrien in /Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/QueryException.php on line 49
我想我们不能做动态条件。我不知道是否有一种方法与原则去做,否则我可能不得不这样做用PHP我想..
这里是我的事件和用户实体的结构:
用户实体:
class User {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false, unique=true)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var integer
*
* @ORM\Column(name="fb_id", type="bigint", nullable=false, unique=true)
*/
private $fb_id;
/**
* @var string
*
* @ORM\Column(name="firstname", type="string", length=100, nullable=false, unique=false)
*/
private $first_name;
/**
* @var string
*
* @ORM\Column(name="lastname", type="string", length=100, nullable=true, unique=false)
*/
private $last_name;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=255, nullable=true, unique=true)
*/
private $email;
/**
* @var integer
*
* @ORM\Column(name="notation", type="integer", nullable=true, unique=true)
*/
private $notation;
/**
* Bidirectional - Many users have Many favorite comments (OWNING SIDE)
*
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Entity\Category", inversedBy="userInterests")
*/
private $interests;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Entity\User", cascade={"persist"})
* @ORM\JoinTable(name="friends",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="friend_user_id", referencedColumnName="id")}
* )
**/
private $friends;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Entity\Request", mappedBy="user", cascade={"remove"}, orphanRemoval=true)
* @ORM\JoinColumn(nullable=true)
*/
private $requests;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Entity\Request", mappedBy="friend", cascade={"remove"}, orphanRemoval=true)
* @ORM\JoinColumn(nullable=true)
*/
private $notifications;
/**
* Bidirectional - Many users have notified they want to go to different events (OWNING SIDE)
*
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Entity\Event", inversedBy="userNotified", cascade={"persist"})
*/
private $eventNotified;
/**
* @var integer
*
* @ORM\Column(name="age", type="integer", length=3, nullable=true, unique=false)
*/
private $age;
/**
* @var string
*
* @ORM\Column(name="description", type="text", nullable=true, unique=false)
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="picture", type="string", length=300, nullable=true, unique=false)
*/
private $picture;
/**
* @var string
*
* @ORM\Column(name="genre", type="string", length=10, nullable=true, unique=false)
*/
private $genre;
/**
* @var boolean
*
* @ORM\Column(name="isregistered", type="boolean", length=1, nullable=false, unique=false)
*/
private $registered;
/**
* @var string
*
* @ORM\Column(name="latitude", type="decimal", length=64, precision=25, scale=20, nullable=true, unique=false)
*/
private $latitude;
/**
* @var string
*
* @ORM\Column(name="longitude", type="decimal", length=64, precision=25, scale=20, nullable=true, unique=false)
*/
private $longitude;
/**
* @var \Entity\Security_Key
*
* @ORM\OneToOne(targetEntity="Entity\Security_Key", cascade={"persist","remove"}, orphanRemoval=true)
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="private_key_id", referencedColumnName="id", unique=true, onDelete="SET NULL")
* })
*/
private $private_key;
/**
* @var boolean
*
* @ORM\Column(name="isavailable", type="boolean", length=1, nullable=false, unique=false)
*/
private $available = 0;
事件实体:
class Event
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", 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=200, precision=0, scale=0, nullable=false, unique=false)
*/
private $name;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Entity\Category", inversedBy="events")
* @ORM\JoinTable(name="categories_events")
*/
private $categories;
/**
* @var \Entity\User
*
* @ORM\ManyToOne(targetEntity="Entity\User", inversedBy="events")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
**/
private $user;
/**
* @var \Entity\Admin
*
* @ORM\ManyToOne(targetEntity="Entity\Admin", inversedBy="events")
* @ORM\JoinColumn(name="admin_id", referencedColumnName="id")
**/
private $admin;
/**
* @var \Entity\Place
*
* @ORM\ManyToOne(targetEntity="Entity\Place", inversedBy="events", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $place;
/**
* @var string
*
* @ORM\Column(name="description", type="text", precision=0, scale=0, nullable=true, unique=false)
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="link", type="string", length=200, nullable=true, unique=false)
*/
private $link;
/**
* @var string
*
* @ORM\Column(name="picture", type="string", length=100, precision=0, scale=0, nullable=true, unique=false)
*/
private $picture;
/**
* @var \DateTime
*
* @ORM\Column(name="date_created", type="datetime", precision=0, scale=0, nullable=false, unique=false)
*/
private $dateCreated;
/**
* @var \DateTime
*
* @ORM\Column(name="date_start", type="datetime", precision=0, scale=0, nullable=true, unique=false)
*/
private $dateStart;
/**
* @var \DateTime
*
* @ORM\Column(name="date_end", type="datetime", precision=0, scale=0, nullable=true, unique=false)
*/
private $dateEnd;
/**
* @var boolean
*
* @ORM\Column(name="confirmed", type="boolean", length=1, nullable=false, unique=false)
*/
private $confirmed;
/**
* Bidirectional - One-To-Many (INVERSE SIDE)
*
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Entity\Request", mappedBy="event")
*/
private $invitations;
/**
* Bidirectional - Many users are intending many events (INVERSE SIDE)
*
* @ORM\ManyToMany(targetEntity="User", mappedBy="eventNotified", cascade={"persist"})
*/
private $userNotified;
你的结果出了什么问题?也许使用innerJoin对朋友? – Gohn67
我不知道把innerjoin放在朋友的哪里。我没有检索到正确的结果集。 –
也许可以将''> leftJoin('USER.friends','FRIENDS')'改为' - > innerJoin('USER.friends','FRIENDS')'? – Gohn67