XPDO ресурсы и связанные TV в одном объекте
Пытаюсь сделать выборку на xPDO сложнее чем в примерах для обучения. Сформировать объект при помощи xPDO содержащий все поля ресурса + его TV и записать в XML.
Есть ресурсы, выбираем те, у которых parent равен определенному id. при этом в объект надо прикрепить все TV поля этого ресурса. пробуем достать граф. modResource — для полей ресурса, TemplatevarResources — связь для получения many TVшек, и TemplateVar связь для получения имени TV.
Ставим лимит 100, в
При доступе к связанным объектам графа вообще в переменных код сниппетов вижу.
Что не так с getCollectionGraph в моем случае?
p.s. для чего это надо? При вызове $resource-getTVValue(x) для каждого ТВ, Мы обращаемся к БД. И если у нас 700 ресурсов по 50 tv параметров, то получаем 35000 отдельных запросов.
Есть ресурсы, выбираем те, у которых parent равен определенному id. при этом в объект надо прикрепить все TV поля этого ресурса. пробуем достать граф. modResource — для полей ресурса, TemplatevarResources — связь для получения many TVшек, и TemplateVar связь для получения имени TV.
$c = $modx->newQuery('modResource');
$c->where(array(
'parent' => '30'
));
$resources = $modx->getCollectionGraph('modResource', '{
"TemplateVarResources":{ "TemplateVar":{} } }',$c);
На тестовом сайте чуть меньше 1000 ресурсов, при выполнении данного скрипта в консоли получаем ошибку Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 8192 bytes)
Мы сожрали всю память.Ставим лимит 100, в
$resources
падает только 4 штуки. (хотя по идее он должен был вывести 100 штук) при увеличении число растет, но не упирается в лимит.При доступе к связанным объектам графа вообще в переменных код сниппетов вижу.
Что не так с getCollectionGraph в моем случае?
p.s. для чего это надо? При вызове $resource-getTVValue(x) для каждого ТВ, Мы обращаемся к БД. И если у нас 700 ресурсов по 50 tv параметров, то получаем 35000 отдельных запросов.
Комментарии: 4
Дабы память не сошла с ума — дергайте их по 1-му в цикле.
Хотите оптимизации — делайте запросы руками, механизмы типа getCollectionGraph 100% жутко прожорливы.
Хотите оптимизации — делайте запросы руками, механизмы типа getCollectionGraph 100% жутко прожорливы.
Вопрос в другом, даже с лимитом в 1
У меня не получается достучаться до значения, имени и ид всех ТВ ресурса.
Если мы добавим после вызова Графа
$c->limit(100);
У меня не получается достучаться до значения, имени и ид всех ТВ ресурса.
Если мы добавим после вызова Графа
foreach ($resources as $resource) {
$count++;
if ($resource->TemplateVarResources) {
foreach ($resource->getMany('TemplateVarResources') as $tvs) {
print_r($tvs);
}
Я не получаю Объект содержащий все привязанные к данному ресурсу ТВшки. Дабы память не сошла с ума — дергайте их по 1-му в цикле.Выполнить сначала GetCount что бы посчитать их количество и идти циклом?
В $data будут все поля ресурса, все его тв со значениями и именами
Обратите внимание, что если у ресурса есть tv со значением по-умолчанию и оно не заполнено, либо установлено значение по-умолчанию, в выборке его не будет, т.к. MODX не создает записей modTemplateVarResource в базе для значений по-умолчанию.
$q = $modx->newQuery('modResource');
$q->leftJoin('modTemplateVarResource', 'TVR', 'TVR.contentid = modResource.id');
$q->leftJoin('modTemplateVar', 'TV', 'TV.id = TVR.tmplvarid');
$q->where([
'modResource.parent' => 30
]);
$q->select([
'modResource.*',
'TVR.*',
'TV.*'
]);
if ($q->prepare() && $q->stmt->execute()) {
$data = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
}
print_r($data);
Обратите внимание, что если у ресурса есть tv со значением по-умолчанию и оно не заполнено, либо установлено значение по-умолчанию, в выборке его не будет, т.к. MODX не создает записей modTemplateVarResource в базе для значений по-умолчанию.
Было решено делать выборку на стороне СУБД при помощи подобного запроса.
$result = $modx->query("
SELECT
t.id,
t.pagetitle,
t.createdon,
t.content,
GROUP_CONCAT(t.idea_date_tech) AS idea_date_tech,
GROUP_CONCAT(t.idea_status) AS idea_status,
GROUP_CONCAT(t.idea_status_info) AS idea_status_info,
GROUP_CONCAT(t.idea_type) AS idea_type,
GROUP_CONCAT(t.idea_internal_status) AS idea_internal_status,
GROUP_CONCAT(t.idea_category) AS idea_category,
GROUP_CONCAT(t.idea_need_money) AS idea_need_money,
GROUP_CONCAT(t.idea_start_date_plan) AS idea_start_date_plan,
GROUP_CONCAT(t.idea_end_date_plan) AS idea_end_date_plan,
GROUP_CONCAT(t.idea_start_date_fact) AS idea_start_date_fact,
GROUP_CONCAT(t.idea_end_date_fact) AS idea_end_date_fact,
GROUP_CONCAT(t.idea_geteconom_IQ) AS idea_geteconom_IQ,
GROUP_CONCAT(t.idea_geteconom_IIQ) AS idea_geteconom_IIQ,
GROUP_CONCAT(t.idea_geteconom_IIIQ) AS idea_geteconom_IIIQ,
GROUP_CONCAT(t.idea_geteconom_IVQ) AS idea_geteconom_IVQ,
GROUP_CONCAT(t.idea_geteconom_total) AS idea_geteconom_total,
GROUP_CONCAT(t.idea_cureeconom_IQ) AS idea_cureeconom_IQ,
GROUP_CONCAT(t.idea_cureeconom_IIQ) AS idea_cureeconom_IIQ,
GROUP_CONCAT(t.idea_cureeconom_IIIQ) AS idea_cureeconom_IIIQ,
GROUP_CONCAT(t.idea_cureeconom_IVQ) AS idea_cureeconom_IVQ,
GROUP_CONCAT(t.idea_cureeconom_total) AS idea_cureeconom_total,
GROUP_CONCAT(t.idea_in_concurs) AS idea_in_concurs,
GROUP_CONCAT(t.idea_concurs_date) AS idea_concurs_date,
GROUP_CONCAT(t.idea_concurs_result) AS idea_concurs_result,
GROUP_CONCAT(t.idea_prem_IQ) AS idea_prem_IQ,
GROUP_CONCAT(t.idea_prem_IIQ) AS idea_prem_IIQ,
GROUP_CONCAT(t.idea_prem_IIIQ) AS idea_prem_IIIQ,
GROUP_CONCAT(t.idea_prem_IVQ) AS idea_prem_IVQ,
GROUP_CONCAT(t.idea_prem_total) AS idea_prem_total,
GROUP_CONCAT(t.departament) AS departament,
t.longtitle,
GROUP_CONCAT(t.function) AS function,
GROUP_CONCAT(t.phone) AS phone ,
t.published
FROM (
SELECT c.id, c.pagetitle, c.createdon, c.content,
CASE cv.tmplvarid
WHEN 18 THEN cv.value
END
AS idea_date_tech,
CASE cv.tmplvarid
WHEN 15 THEN cv.value
END
AS idea_status,
CASE cv.tmplvarid
WHEN 19 THEN cv.value
END
AS idea_status_info,
CASE cv.tmplvarid
WHEN 20 THEN cv.value
END
AS idea_type,
CASE cv.tmplvarid
WHEN 46 THEN cv.value
END
AS idea_internal_status,
CASE cv.tmplvarid
WHEN 45 THEN cv.value
END
AS idea_category,
CASE cv.tmplvarid
WHEN 47 THEN cv.value
END
AS idea_need_money,
CASE cv.tmplvarid
WHEN 21 THEN cv.value
END
AS idea_start_date_plan,
CASE cv.tmplvarid
WHEN 22 THEN cv.value
END
AS idea_end_date_plan,
CASE cv.tmplvarid
WHEN 23 THEN cv.value
END
AS idea_start_date_fact,
CASE cv.tmplvarid
WHEN 24 THEN cv.value
END
AS idea_end_date_fact,
CASE cv.tmplvarid
WHEN 25 THEN cv.value
END
AS idea_geteconom_IQ,
CASE cv.tmplvarid
WHEN 26 THEN cv.value
END
AS idea_geteconom_IIQ,
CASE cv.tmplvarid
WHEN 27 THEN cv.value
END
AS idea_geteconom_IIIQ,
CASE cv.tmplvarid
WHEN 28 THEN cv.value
END
AS idea_geteconom_IVQ,
CASE cv.tmplvarid
WHEN 29 THEN cv.value
END
AS idea_geteconom_total,
CASE cv.tmplvarid
WHEN 31 THEN cv.value
END
AS idea_cureeconom_IQ,
CASE cv.tmplvarid
WHEN 32 THEN cv.value
END
AS idea_cureeconom_IIQ,
CASE cv.tmplvarid
WHEN 33 THEN cv.value
END
AS idea_cureeconom_IIIQ,
CASE cv.tmplvarid
WHEN 34 THEN cv.value
END
AS idea_cureeconom_IVQ,
CASE cv.tmplvarid
WHEN 35 THEN cv.value
END
AS idea_cureeconom_total,
CASE cv.tmplvarid
WHEN 36 THEN cv.value
END
AS idea_in_concurs,
CASE cv.tmplvarid
WHEN 38 THEN cv.value
END
AS idea_concurs_date,
CASE cv.tmplvarid
WHEN 39 THEN cv.value
END
AS idea_concurs_result,
CASE cv.tmplvarid
WHEN 40 THEN cv.value
END
AS idea_prem_IQ,
CASE cv.tmplvarid
WHEN 41 THEN cv.value
END
AS idea_prem_IIQ,
CASE cv.tmplvarid
WHEN 42 THEN cv.value
END
AS idea_prem_IIIQ,
CASE cv.tmplvarid
WHEN 43 THEN cv.value
END
AS idea_prem_IVQ,
CASE cv.tmplvarid
WHEN 44 THEN cv.value
END
AS idea_prem_total,
CASE cv.tmplvarid
WHEN 14 THEN cv.value
END
AS departament,
c.longtitle,
CASE cv.tmplvarid
WHEN 16 THEN cv.value
END
AS function,
CASE cv.tmplvarid
WHEN 17 THEN cv.value
END
AS phone,
c.published
FROM modx_site_content c
left join modx_site_tmplvar_contentvalues cv on c.id = cv.contentid
inner join modx_site_tmplvars tv on cv.tmplvarid = tv.id
where c.parent = 30
) t
GROUP BY t.id
order by t.pagetitle;
");
$resources = $result->fetchall(PDO::FETCH_ASSOC);
Не знаю на сколько решение элегантное, но так мы не тянем те поля ресурса, что нам не нужны в память. работает быстро.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.