Наверх

Билдер SQL запросов для modx, minishop2 и TV

В разделе «Репосты» расположены чужие статьи, которые мне понравились или показались полезными.

Всем привет, просили меня недавно сделать выгрузку со старого сайта на modx с более чем 200к товаров, т.к. я уже давно не работал с modx, абсолютно забыв методы API, а также помня, насколько медленно и ресурсозатратно оно работает было решено писать SQL напрямую и все бы ничего, пока я не увидел структуру tv полей. Руками писать SQL с выборкой необходимых TV было адским адом, и было решено за часик накидать мини билдер SQL запросов

Получился примерно такой в использовании билдер, по мне покрывает 100% моих задач в формировании SQL для выгрузок из modx & ms2:
$builder = new SimpleBuilder();
$builder->addResourceFields('id', 'pagetitle', 'longtitle')
    ->addMs2Fields('article', 'price')
    ->addTvFields('price_opt', 'product_time', 'valute', 'remains', 'product_tax')
    ->where('deleted', '=', false)
    ->where('published', '=', true)
    ->where('class_key', '=', 'msProduct')
    ->where('remains', '!=', 0)
    ->whereNotNull('remains')
    ->whereIn('id', [18559, 18560])
    ->limit(1)
    ->offset(1)
;
$sql = $builder->sql();

$products = $modx->query($sql)->fetchAll(PDO::FETCH_ASSOC);

Под катом код и результат SQL который формирует билдер
Если хочется сразу к коду


И так, к SQL который сформировал код выше:
SELECT resource.id,
       resource.pagetitle,
       resource.longtitle,
       ms2.article,
       ms2.price,
       price_opt_table.value    as price_opt,
       product_time_table.value as product_time,
       valute_table.value       as valute,
       remains_table.value      as remains,
       product_tax_table.value  as product_tax
FROM modx_site_content as resource
         LEFT JOIN modx_ms2_products as ms2 on resource.id = ms2.id
         LEFT JOIN modx_site_tmplvars as price_opt_tv_name on price_opt_tv_name.name = 'price_opt'
         LEFT JOIN modx_site_tmplvar_contentvalues as price_opt_table
                   on resource.id = price_opt_table.contentid and price_opt_table.tmplvarid = price_opt_tv_name.id
         LEFT JOIN modx_site_tmplvars as product_time_tv_name on product_time_tv_name.name = 'product_time'
         LEFT JOIN modx_site_tmplvar_contentvalues as product_time_table
                   on resource.id = product_time_table.contentid and
                      product_time_table.tmplvarid = product_time_tv_name.id
         LEFT JOIN modx_site_tmplvars as valute_tv_name on valute_tv_name.name = 'valute'
         LEFT JOIN modx_site_tmplvar_contentvalues as valute_table
                   on resource.id = valute_table.contentid and valute_table.tmplvarid = valute_tv_name.id
         LEFT JOIN modx_site_tmplvars as remains_tv_name on remains_tv_name.name = 'remains'
         LEFT JOIN modx_site_tmplvar_contentvalues as remains_table
                   on resource.id = remains_table.contentid and remains_table.tmplvarid = remains_tv_name.id
         LEFT JOIN modx_site_tmplvars as product_tax_tv_name on product_tax_tv_name.name = 'product_tax'
         LEFT JOIN modx_site_tmplvar_contentvalues as product_tax_table
                   on resource.id = product_tax_table.contentid and product_tax_table.tmplvarid = product_tax_tv_name.id
WHERE deleted = 0
  AND published = 1
  AND class_key = 'msProduct'
  AND remains_table.value != 0
  AND remains_table.value IS NOT NULL
  AND resource.id IN (18559, 18560)
LIMIT 1 OFFSET 1

Из приятного:

Прирост скорости по сравнению с $modx->getCollection() более чем в 10 раз (!) не удивительно соб-но =\.
Если колонка WHERE присутствует хоть в одном из SELECT, то ему автоматически подставится префикс, а значит отсутствие конфликтов, и можно указывать прямо так:
$builder->where('id', '=', 1);
т.е. без указания таблицы, к которой принадлежит эта колонка

Из неприятного:

  1. Нет выборки картинок ms2_product_files, для моей задачи этого не надо было, по этому и не писал
  2. Он написан за час, а эта заметка за 10 минут, не исключено наличие ошибок, а качество кода оставляет желать лучшего
  3. Если колонка ресурса будет пересекаться по названию например с колонкой TV вы наверняка получите ошибку, будьте внимательны
  4. Дефолтное значение tv параметра не подтягивается, подставляйте его в коде при выгрузке, а лучше вообще не используйте

Ну и в целом код написан больше для тех, кто понимает что делает и знает где и что подкрутить, в случае если в его запросе что то сформируется не так

Код смотреть тут

Требования: php >= 7.1

Источник: modx.pro/solutions/22711


0 комментариев

    Авторизация

    через сервис Loginza:


    Шаблоны MODX

    1 2 Дальше »

    Объектная
    модель
    MODX