如何在doctrine mongodb中执行嵌套引用查询

时间:2014-11-27 11:54:18

标签: php mongodb symfony doctrine-orm doctrine

这描述了我当前的架构:

/**
 * @MongoDB\Document(repositoryClass="St\AppBundle\Repository\TaxiStateRepository", requireIndexes=true)
 * @MongoDB\Index(keys={"location"="2d"})
 */
class TaxiState 
{

    /**
     * @MongoDB\ReferenceOne(targetDocument="Taxi", simple=true, inversedBy="taxiState")
     * @MongoDB\Index
     */
    protected $taxi;
..
}

/**
 * @MongoDB\Document(repositoryClass="St\AppBundle\Repository\TaxiRepository", requireIndexes=true)
 */
class Taxi 
{
    /**
     * @MongoDB\ReferenceOne(targetDocument="Driver", simple=true)
     * @MongoDB\Index
     */
    protected $driver;
    ..
}

/**
 * @MongoDB\Document(repositoryClass="St\AppBundle\Repository\DriverRepository", requireIndexes=true)
 */
class Driver
{
    /**
     * @MongoDB\EmbedOne(targetDocument="DriverAccount")
     * @MongoDB\Index
     */
    protected $driverAccount;
    ..
}

/** @MongoDB\EmbeddedDocument */
class DriverAccount
{
    /**
     * @MongoDB\String
     * @Assert\NotBlank()
     * @Assert\Choice(choices = {"enabled","disabled"}, message="please chose a valid status");         * @MongoDB\Index
     */
    protected $status;

我基本上想要运行一个过滤掉已禁用的驱动程序帐户的查询..这样的事情:

return $this->createQueryBuilder()
    ->field('taxi.driver.driverAccount.status')->equals("enabled")
    ->getQuery()
    ->getSingleResult();

它抱怨它没有index taxi.driver等。我花了一整天时间查看了教条中的by directional reference文档,但这些例子很稀疏..帮助?

供参考..这是在我引入那条疯狂的线之前正常运行的查询:

    return $this->createQueryBuilder()
        ->field('status')->equals('available')
        ->field('taxi')->notIn($taxiObj)
        ->field('location')->near((float)$location->getLongitude(), (float)$location->getLatitude())
        ->distanceMultiplier(self::EARTH_RADIUS_KM)
        ->maxDistance($radius/111.12)
        ->getQuery()
        ->execute();

1 个答案:

答案 0 :(得分:0)

万一你想知道我是如何解决的#34;这个(这是一个非常讨厌的答案......但是,你做的就是你做得对吗?)这就是我得到的:

/**
 * Find near enabled taxi without rejected request taxi
 *
 * @param Document\Location $location
 * @param int $radius
 * @param array $taxis
 * @return Document\TaxiState
 */
public function findEnabledNearTaxiWithoutRejectRequest(Document\Location $location, $radius = self::SEARCH_RADIUS, $taxis = array(), $logger)
{
    $taxiObj = array_map(function ($item) {
        return new \MongoId($item);
    }, $taxis);

    //ST-135 change to near, spherical, distanceMultiplier and maxDistance in KM
    $allTaxiStates = $this->createQueryBuilder()
        ->field('status')->equals('available')
        ->field('taxi')->notIn($taxiObj)
        ->field('location')->near((float)$location->getLongitude(), (float)$location->getLatitude())
        ->distanceMultiplier(self::EARTH_RADIUS_KM)
        ->maxDistance($radius/111.12)
        ->getQuery()
        ->execute();

    $this->addIdsOfDisabledTaxiStates($taxiObj, $allTaxiStates);

    if (count($taxiObj) > 0) {
        $logger->info("There are ".count($taxiObj)." taxis excluded while looking for taxis to respond to a requst: ".$this->getMongoIdsStr($taxiObj));
    }

    return $this->createQueryBuilder()
        ->field('status')->equals('available')
        ->field('taxi')->notIn($taxiObj)
        ->field('location')->near((float)$location->getLongitude(), (float)$location->getLatitude())
        ->distanceMultiplier(self::EARTH_RADIUS_KM)
        ->maxDistance($radius/111.12)
        ->getQuery()
        ->getSingleResult();
}

/**
 * Get the Mongo Ids of disabled taxi States
 *
 * @param $ids existing array of ids we want to append to (passed by reference)
 * @param $taxiStates array of Document\TaxiState
 * @return array of MongoIds of disabled taxi states
 * @author Abdullah
 */
private function addIdsOfDisabledTaxiStates(&$ids, $taxiStates)
{
    foreach ($taxiStates as $taxiState) {
        if ($taxiState->getTaxi()->getDriver()->getDriverAccount()->getStatus() != DriverAccountModel::STATUS_ENABLED) {
            $mongoId = new \MongoId($taxiState->getTaxi()->getId());
            array_push($ids, $mongoId);
        }
    }

    return $ids;
}