Php Doctrine ODM查询生成器嵌套子字段查找
我对集合元素的嵌套查找有以下问题:Php Doctrine ODM查询生成器嵌套子字段查找,php,mongodb,symfony,doctrine-orm,Php,Mongodb,Symfony,Doctrine Orm,我对集合元素的嵌套查找有以下问题: class User { /* * @MongoDB\Id(strategy="auto") */ protected $id; } class Network { /* * @MongoDB\ReferenceOne(targetDocument="User") */ protected $owner; } class Connection { /* * @Mong
class User
{
/*
* @MongoDB\Id(strategy="auto")
*/
protected $id;
}
class Network
{
/*
* @MongoDB\ReferenceOne(targetDocument="User")
*/
protected $owner;
}
class Connection
{
/*
* @MongoDB\ReferenceOne(targetDocument="Network")
*/
protected $network;
}
如何在Doctrine ODM查询生成器中找到所有用户自己的网络连接(按用户id)?
另外,原生mongodb查询也可以接受。
不幸的是,您不能直接按引用文档的字段进行查询,最好由关系数据库处理。在MongoDB中,这当然是可能的,但需要多个查询:首先找到用户所属的网络,然后应该找到网络的连接
public function findByUserId($userId)
{
return $this->dm->getRepository(Connection::class)->findBy([
'network.owner.$id' => new MongoId($userId),
]);
}
当然,获取网络标识符列表以进行连接查询就足够了。这可以在查询生成器的帮助下轻松完成:
$networkQb = $this->dm->getRepository(Network::class)->createQueryBuilder();
$networkQb->field('owner.$id')->equals($userId);
$networkQb->select('_id'); // Limit results to the ID of the network only
$networkQb->hydrate(false); // Don't return Network objects but only plain array
$networkResults = $networkQb->getQuery()->toArray();
$networkIdList = array_map(function($result) { return $result['_id']; }, $networkResults); // This converts array(array("_id" => "1234"), array("_id" => "5678")) to array("1234","5678")
// Then we'll make the actual query for the connections, based on the id list of the networks
$connectionQb = $this->dm->getRepository(Connection::class)->createQueryBuilder();
$connectionQb->field('network.$id')->in($networkIdList);
$connections = $connectionQb->getQuery()->toArray();
这种查询仍然相对较快,因为每个用户只有几个网络。对于@MongoDB\ReferenceOne,必须使用查询生成器的references()方法
PS:使用includesReferenceTo()a@MongoDB\ReferenceMany此方法不适用于
@ReferenceOne
或@ReferenceMany
字段,但确实适用于@EmbedOne
或@embedmanny
。
$user = $dm->getRepository('User')->findOneById($userId);
$queryBuilder = $dm->getRepository('Network')->createQueryBuilder()
->field('owner')->references($user);
$ownNetworkConnections = $queryBuilder->getQuery()->execute();