Как я могу получить все дерево в одном запросе с доктриной? - PullRequest
4 голосов
/ 26 февраля 2010

Этот фрагмент с официального сайта работает как положено:

$treeObject = Doctrine::getTable('Category')->getTree();
$rootColumnName = $treeObject->getAttribute('rootColumnName');

foreach ($treeObject->fetchRoots() as $root) {
  $options = array(
      'root_id' => $root->$rootColumnName
  );
  foreach($treeObject->fetchTree($options) as $node) {
    echo str_repeat(' ', $node['level']) . $node['name'] . "\n";
  }
}

Но я вижу, что к базе данных отправляются десятки запросов.

Как я могу сделать это во рту?

Ответы [ 5 ]

3 голосов
/ 01 марта 2010

Попробуйте это:

Doctrine_Core::getTable('YourTableWithTree')->createQuery('tree')
    ->addOrderBy('tree.root_id ASC')
    ->addOrderBy('tree.lft ASC');
1 голос
/ 22 августа 2013

Существует алгоритм, встроенный в O (n), который строит полное дерево с m уровнями без учета порядка сбора

https://gist.github.com/mmoreram/6292326

0 голосов
/ 27 февраля 2010

Просто извлеките всю таблицу с DQL-запросом, прежде чем смотреть на дерево. Доктрина достаточно умна, чтобы видеть, что она уже загрузила узлы дерева.

* 1003 Е.Г. *

$q = Doctrine_Query::create()->from('Category c')->orderBy('c.level');
$categories = $q->execute();

Если в вашей таблице n деревьев (то есть n корневых узлов), то первые n объектов в $ категориях - это корни вашего дерева.

В зависимости от вашего варианта использования, вы можете сортировать или увлажнять по-разному. Например, чтобы распечатать дерево (как в вашем примере), вы можете сделать это:

$q = Doctrine_Query::create()
     ->select('c.name, c.level')
     ->from('Category c');
     ->orderBy('c.lft')
     ->setHydrationMode(Doctrine::HYDRATE_SCALAR);

$categories = $q->execute();

foreach ($categories as $category) {
    print str_repeat(' ', $category['c_level']) . $category['c_name'] . "\n";
}

Это приводит к одному запросу.

0 голосов
/ 27 февраля 2010

Разве это не помогает?

$treeObject = Doctrine::getTable('Category')->getTree();
$tree = $treeObject->fetchTree();

foreach ($tree as $node) {
    echo str_repeat('  ', $node['level']) . $node['name'] . "\n";
}
0 голосов
/ 26 февраля 2010

Вы можете получить доступ к базовой таблице как к обычной таблице в Doctrine с помощью запроса, построенного с getBaseQuery(). В API отсутствует описание этого метода, но проверьте исходный код:

public function getBaseQuery()
{
    if ( ! isset($this->_baseQuery)) {
        $this->_baseQuery = $this->_createBaseQuery();
    }
    return $this->_baseQuery->copy();
}

// ...

private function _createBaseQuery()
{
    $this->_baseAlias = "base";
    $q = Doctrine_Core::getTable($this->getBaseComponent())
        ->createQuery($this->_baseAlias)
        ->select($this->_baseAlias . '.*');
    return $q;
}
...