Doctrine ODM Query构建器嵌套子字段查找

时间:2013-11-13 12:44:26

标签: php mongodb symfony doctrine-orm

我对嵌套查找集合元素有以下问题:

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查询也会接受。

3 个答案:

答案 0 :(得分:1)

public function findByUserId($userId)
{
    return $this->dm->getRepository(Connection::class)->findBy([
        'network.owner.$id' => new MongoId($userId),
    ]);
}

答案 1 :(得分:0)

不幸的是,您不能直接通过引用文档的字段进行查询,最好由关系数据库来处理。在MongoDB中,这当然是可能的,但需要多个查询:首先你找到用户所属的网络,然后你应该找到网络的连接。

当然,只需获取网络标识符列表即可进行连接查询。这可以在查询构建器的帮助下轻松完成:

$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();

只要每个用户只有几个网络,这种查询仍然相对较快。

答案 2 :(得分:0)

您必须使用查询构建器的 references() 方法来获取 @MongoDB \ ReferenceOne ,例如https://doctrine-mongodb-odm.readthedocs.org/en/latest/reference/query-builder-api.html

$user = $dm->getRepository('User')->findOneById($userId);

$queryBuilder = $dm->getRepository('Network')->createQueryBuilder()
                   ->field('owner')->references($user);

$ownNetworkConnections = $queryBuilder->getQuery()->execute();


PS :使用 includesReferenceTo() a @MongoDB \ ReferenceMany