Проблемы с фильтрацией ресурсов (больше 2000шт.)
Стоит задача отфильтровать ресурсы: вывести те ресурсы, у которых больше 20 просмотров (HitsPage), комментов больше 0 (Tickets), и которые опубликованы больше месяца назад.
Написал сниппет, но при обработке большого количества ресурсов страница с вызовом сниппета не загружается. Как оптимизировать код?
Написал сниппет, но при обработке большого количества ресурсов страница с вызовом сниппета не загружается. Как оптимизировать код?
$mounth = 2629743;
$date = strtotime('now')-$mounth;
$where = array(
'parent' => 19,
'publishedon:<' => $date
);
$resources = $modx->getCollection('modResource', $where);
foreach ($resources as $k => $res) {
//получаем id
$id = $res->get('id');
//получаем количество комментов
$q = $modx->newQuery('modResource', $id);
$q->leftJoin('TicketThread','TicketThread', "`TicketThread`.`name` = 'resource-{$id}'");
$q->leftJoin('TicketComment','TicketComment', "`TicketThread`.`id` = `TicketComment`.`thread`");
$q->select('COUNT(`TicketComment`.`id`) as `comments`');
$count = 0;
if ($q->prepare() && $q->stmt->execute()) {
$count = (integer) $q->stmt->fetch(PDO::FETCH_COLUMN);
}
//получаем дату, количество просмотров и заголовок
$date = $res->get('publishedon');
$hits = $res->getTVValue(3);
$titles = $res->get('pagetitle');
//если опубликован больше месяца назад, просмотров больше 20 и комментов больше 0, то выводим
if ($hits >= 20 and $count > 0) {
$output .= $date. " | П: ". $hits. " | К: ". $count. "</br>". $titles. "<hr>";
}
}
return $output; Комментарии: 6
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
modxclub.ru/topics/xpdogetiterator-vmesto-xpdogetcollection.html
В критерию можно добавить выбор только нужных колонок (publishedon, pagetitle, id)
Можно сразу присоединить и таблицу с TV hits по contentid и tmplvarid = 3
В случае getCollection и getIterator вы получаете объекты xpdo, из которых вы можете получить подготовленные данные через метод get.
А в данном случае вы получаете результат из базы данных
Я вчитался в код и офигел… Сначала выбираются минимум 2000 страниц, после чего для каждой из них идет запрос к базе.
Да, тут вообще вопрос в другом — как избавится от такого количества запросов.
Очень плохой код.
Как это сейчас работает: сначала через getCollection забираются 2000+ ресурсов, которые опубликованы. Далее мы получаем их id и для каждого делаем запрос к бд!
Это очень плохая идея.
Как минимум те же id можно получить через newQuery — так будет быстрее.
А во вторых желательно сделать 1 запрос к бд, а не 2001.
Почитай мануалы.
А вообще я бы примерно так сделал (вообще не гарантирую, что будет работать, пишу на глазок).
Вариант такого типа будет работать в сотни раз быстрее
Условия выборки немного изменились: вывести статьи, у которых просмотров меньше 20, количество комментов = 0, и, которые опубликованы больше трех недель назад.