【发布时间】:2014-02-02 05:34:28
【问题描述】:
我将我的用户链接到事件实体。基本上,用户可能想参加几个活动,通过多对多,我正在注册谁想参加 X 活动。
我需要使用 Doctrine 构建一个查询来获取用户是否可用(可用设置为 1)或者他们是否计划根据他们的位置参加活动(我也有这个)。第一个条件很好。但是对于第二个,我需要确保用户至少有一个他想去的事件,注册在多对多关系中:eventNotified。
在 Php 中,我会执行一个 foreach 循环,然后判断 $user->getEventNotified() 是否不是空数组(或 null ),但这会使我得到太多结果。我想用 SQL 或 DQL 选择它
我该怎么做?
这是我到目前为止所取得的成就,如果用户想要参加一个活动,我只需要添加一个 OR 条件(eventNotified 不是 null 吗?):
//We only want to return users nearby who are available OR who
$qb = $this->_em->getRepository( 'Entity\User' )->createQueryBuilder('a');
$qb->andwhere( 'a.latitude > :minLat' );
$qb->andWhere( 'a.latitude < :maxLat' );
$qb->andWhere( 'a.longitude > :minLng' );
$qb->andWhere( 'a.longitude < :maxLng' );
$qb->andWhere( 'a.available = 1' );
$qb->add( 'orderBy', $qb->expr()->sum( 'a.latitude - :lat', 'a.longitude - :lng' ));
$array = array(
'minLat' => $minLat,
'maxLat' => $maxLat,
'minLng' => $minLng,
'maxLng' => $maxLng,
'lat' => $lat,
'lng' => $lng
);
$qb->setParameters( $array );
// $qb->setFirstResult( $offset );
// $qb->setMaxResults( $limit );
// print_r(array(
// 'sql' => $qb->getQuery()->getSQL(),
// 'parameters' => $qb->getQuery()->getParameters(),
// ));
$usersNearby = $qb->getQuery()->getResult();
return $usersNearbt;
这是我的用户实体:
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;
...
编辑:
感谢下面的解决方案,我对其进行了一些调整(和一些优化):
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select( 'USER', 'EVENT', 'c', 'p' )
->from( 'Entity\User', 'USER' )
->innerJoin( 'USER.eventNotified', 'EVENT' )
->leftJoin( 'EVENT.categories', 'c' )
->leftJoin( 'EVENT.place', 'p' )
->add('where', $qb->expr()->andX(
$qb->expr()->between('USER.latitude', ':minLat', ':maxLat'),
$qb->expr()->between('USER.longitude', ':minLng', ':maxLng')
)
)
->add( 'orderBy', $qb->expr()->sum( 'USER.latitude - :lat', 'USER.longitude - :lng' ) );
$array = array(
'minLat' => $minLat,
'maxLat' => $maxLat,
'minLng' => $minLng,
'maxLng' => $maxLng,
'lat' => $lat,
'lng' => $lng
);
$qb->setParameters( $array );
$usersNearby = $qb->getQuery()->getResult();
【问题讨论】:
标签: php sql symfony doctrine-orm dql