Я создаю REST API для вывода конечных точек / проектов. Я создал две модели:
Проекты:
class Projects extends BaseModel { public function initialize() { $this->hasMany('id', 'Participants', 'projectId'); } }
Участники:
class Participants extends BaseModel { public function initialize() { $this->belongsTo('projectId', 'Projects', 'id'); } }
Допустим, у меня есть 10 проектов: (1 запрос)
$results = Projects::find();
Я просматриваю все 10 из них, но хочу, чтобы все участники тоже:
foreach($results as $result) { echo $result->participants; // 1 query }
Поэтому в конце цикла Phalcon сделал дополнительный запрос для каждого проекта.
Эти запросы были сделаны путем доступа к участникам $ result->, итерации более 10 проектов:
SELECT IF(COUNT(*)>0, 1 , 0) FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME`='projects' DESCRIBE `projects` SELECT `projects`.`id`, `projects`.`title`, `projects`.`client`, `projects`.`color`, `projects`.`start_date`, `projects`.`end_date`, `projects`.`notes`, `projects`.`stateId`, `projects`.`created_at`, `projects`.`updated_at` FROM `projects` SELECT IF(COUNT(*)>0, 1 , 0) FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME`='project_participants' DESCRIBE `project_participants` SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0
Есть ли способ запросить отношения перед рукой, поэтому это будет один запрос. Когда я использую построитель запросов, предоставленный Phalcon, я не могу получить доступ к -> участникам таким же образом.
Я закончил с помощью Query Builder, namespacing всех столбцов
$builder = $modelsManager->createBuilder(); $builder->columns($columns) ->from('Projects') ->leftJoin('Participants') ->getQuery() ->execute();
Столбцы:
Projects.id as projects_id ... Participants.id as participants_id Participants.projectId as participants_projectId
Поскольку доступ -> участников к результату, созданному Query Builder, также вызывал дополнительные запросы.
Для доступа -> участников так же, как с помощью QueryBuilder, вам нужно будет создать соединение в Query.
Пример кода может быть примерно таким:
$queryBuilder = $this->getDI()->getModelsManager() ->createBuilder() ->columns(['p.id','participants.*']) ->addFrom('Entity\Projects', 'p') ->leftJoin('Entity\Participants', 'participants.projectId = p.id', 'participants') ->groupBy('p.id, participants.id') ->orderBy('p.id ASC'); $resultSet = $queryBuilder->getQuery()->execute();
groupBy()
используется здесь, чтобы сделать результат, возможно, многомерным.
Такой запрос (проверенный в PgSQL) заставил Phalcon создать некоторые последующие объекты участников ResultSet pi
внутри Resultsets для проектов p
.
Вы все еще можете перебирать его, используя foreach()
но в конце концов, я не уверен, что это уменьшило количество окончательных запросов .
Fireing $result = $resultSet->toArray()
сделал $result['pi']
остался как Resultset, поэтому вы должны быть осторожны в этом. Вы можете заставить его сбрасывать как массивы, определяя точные столбцы в параметрах columns()
. У этого есть недостаток – вы больше не будете получать прибыль от groupBy()
, по крайней мере, на Phalcon 1.3.2 и PHP 5.5.3, которые работают здесь.
Существует большая библиотека для активной загрузки на фалкон.
stibiumz phalcon нетерпевая загрузка
Эта библиотека решает N + 1 запросов для отношений. Он уже включен в инкубатор фалкона. Я использую его уже на производстве.
Он создает запрос с использованием предложения IN и заполняет модели результатами.
У многих есть:
SELECT * FROM main SELECT * FROM related WHERE x.id IN (results from the previous resultset)