UMIhelp

Разработка сайта на UMI.CMS => Макросы UMI.CMS => Тема начата: atach от 20 Июня 2014, 19:18:18

Название: API.Selector повторное использование результата выборки ...
Отправлено: atach от 20 Июня 2014, 19:18:18
Добрый день! Подскажите такой вопрос.
делаю выборку через Selector, по определенным параметрам.
Получаю результат. А как можно сделать дальнейшую выборку но только из этого полученного результата.

$pages = new selector('pages');            
$pages->types('object-type')->id(121);
$pages->where('hierarchy')->page(6)->childs(3);
$pages->option('or-mode')->field('fieldname');
$pages->where('fieldname')->equals('value');
$result = $pages->result();

Вот както я могу дальше использовать полученный $result, что бы опять сделать выборку через "selector".

 Если нет то можеь кто то подскажет как делать дальше выборку?
Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: e.ioffe от 20 Июня 2014, 20:16:30
Я обычно в цикле пробегаюсь и получаю id элементов из первого selector, а затем делаю фильтрацию по ним во втором selector.
Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: atach от 20 Июня 2014, 20:32:52
Да точно такой же ответ пришел от поддержки:

Цитировать
записываете id полученных объектов в массив

foreach($pages as $page){
 
                $mass[] = $page->id;
        }
в следующей выборке, сначала отбираете объекты у которых id равно id из массива

$final = new selector('pages'); 
$final->types('object-type')->id(121);
$final->where('id')->equals($mass);
далее, пишите дополнительные условия.
Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: ilyar от 20 Июня 2014, 20:49:20
Насколько мне известно selector с помощью хелперов строит запрос, его можно дополнять:

<?php

$pages = new selector('pages');           
$pages->types('object-type')->id(121);
$pages->where('hierarchy')->page(6)->childs(3);
$pages->option('or-mode')->field('fieldname');
$pages->where('fieldname1')->equals('value');

$result = $pages->result();

$pages->where('fieldname2')->equals('value');

$result = $pages->result();

переопределять:

<?php

$pages = new selector('pages');           
$pages->types('object-type')->id(121);
$pages->where('hierarchy')->page(6)->childs(3);
$pages->option('or-mode')->field('fieldname');
$pages->where('fieldname1')->equals('value');

$result = $pages->result();

$pages->where('fieldname1')->equals('value2');

$result = $pages->result();

 и сбросив  $pages->flush() построить заново, еще можно получить $pages->query() построенный SQL-запрос, дальше работать с ним.

Уточни что именно ты хочешь делать с полученной выборкой?
Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: atach от 20 Июня 2014, 20:55:16
на определенных страницах уже есть выборка по "selector" и есть результат в виде массива ($result = $pages->result();) и дальше мне нужно из полученной выборки делать дальнейющую выборку ...

Сразу я не могу делать это в одной выборки т.к. присутвуют противоречующие одни и теже поля с дизюнкцией "ИЛИ" и "И" ...Поэтому сначала отсеивается одна часть, потом другая

Я просто не знаю такая схема работает

$result = $pages->result();
$pages->where('fieldname1')->equals('value2');
$result = $pages->result();

Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: ilyar от 21 Июня 2014, 11:03:21
на определенных страницах уже есть выборка по "selector" и есть результат в виде массива ($result = $pages->result();) и дальше мне нужно из полученной выборки делать дальнейющую выборку ...

Сразу я не могу делать это в одной выборки т.к. присутвуют противоречующие одни и теже поля с дизюнкцией "ИЛИ" и "И" ...Поэтому сначала отсеивается одна часть, потом другая

Все равно не понятно, что же ты пытаешься реализовать.

Я просто не знаю такая схема работает

$result = $pages->result();
$pages->where('fieldname1')->equals('value2');
$result = $pages->result();


Тут я оказался не прав так работать не будет, потому что как только приватный метод executor класса selector выполнен, перестраивать запрос можно только после сброса результата и мое предположение, что можно переопределить условие тоже не верно:

<?php
require 'standalone.php';

header('Content-type: text/plain; charset=utf-8');

$pages = new selector('pages');
$pages->types('object-type')->id(113);
$pages->where('hierarchy')->page(24)->childs(3);

echo $pages->query().PHP_EOL;
echo $pages->length.PHP_EOL;

$pages->flush();
$pages->where('city')->equals(7997);
echo $pages->query().PHP_EOL;
echo $pages->length.PHP_EOL;

$pages->flush();
$pages->where('city')->equals(7994);
echo $pages->query().PHP_EOL;
echo $pages->length.PHP_EOL;

/* result

SELECT DISTINCT SQL_CALC_FOUND_ROWS h.id as id, h.rel as pid
FROM cms3_hierarchy h, cms3_object_types t, cms3_permissions p, cms3_hierarchy_relations hr, cms3_objects o

WHERE o.type_id IN (113) AND t.id = o.type_id AND h.lang_id = '2' AND h.is_deleted = '0' AND h.is_active = '1' AND (p.rel_id = h.id AND p.level & 1 AND p.owner_id IN(298)) AND h.id = hr.child_id AND (hr.level <= 3 AND hr.rel_id = '24') AND h.obj_id = o.id

ORDER BY h.ord ASC

50
SELECT DISTINCT SQL_CALC_FOUND_ROWS h.id as id, h.rel as pid
FROM cms3_hierarchy h, cms3_object_types t, cms3_permissions p, cms3_hierarchy_relations hr, cms3_objects o
LEFT JOIN cms3_object_content oc_425_lj ON oc_425_lj.obj_id=o.id AND oc_425_lj.field_id = '425'
WHERE o.type_id IN (113) AND t.id = o.type_id AND (oc_425_lj.rel_val = '7997') AND h.lang_id = '2' AND h.is_deleted = '0' AND h.is_active = '1' AND (p.rel_id = h.id AND p.level & 1 AND p.owner_id IN(298)) AND h.id = hr.child_id AND (hr.level <= 3 AND hr.rel_id = '24') AND h.obj_id = o.id

ORDER BY h.ord ASC

27
SELECT DISTINCT SQL_CALC_FOUND_ROWS h.id as id, h.rel as pid
FROM cms3_hierarchy h, cms3_object_types t, cms3_permissions p, cms3_hierarchy_relations hr, cms3_objects o
LEFT JOIN cms3_object_content oc_425_lj ON oc_425_lj.obj_id=o.id AND oc_425_lj.field_id = '425'
WHERE o.type_id IN (113) AND t.id = o.type_id AND ((oc_425_lj.rel_val = '7997' AND oc_425_lj.rel_val = '7994')) AND h.lang_id = '2' AND h.is_deleted = '0' AND h.is_active = '1' AND (p.rel_id = h.id AND p.level & 1 AND p.owner_id IN(298)) AND h.id = hr.child_id AND (hr.level <= 3 AND hr.rel_id = '24') AND h.obj_id = o.id

ORDER BY h.ord ASC

0
 
*/

Как можно видеть повторное указание условия с тем же полем дополняет запрос.
 
Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: ilyar от 21 Июня 2014, 11:23:45
Вижу два развития развития работать с SQL-запросом или делать проверки объектов из результатов выборки:

<?php
require 'standalone.php';

header('Content-type: text/plain; charset=utf-8');

$pages = new selector('pages');
$pages->types('object-type')->id(113);
$pages->where('hierarchy')->page(24)->childs(3);
$pages->where('city')->equals(7997);

echo $pages->length.PHP_EOL;
$result = array();
foreach($pages as $page) { /** @var umiHierarchyElement $page*/

    if($page->duration >= 3) { // some condition
        $result[$page->id] = $page;
    }
   
}
echo count($result).PHP_EOL;

Ну или так как советует e.ioffe и поддержка.

Конечное решение зависит от что ты пытаешься решить, может быть решение лежит совершенно в другом месте нежели ты думаешь.
Название: Re:API.Selector повторное использование результата выборки ...
Отправлено: admin от 22 Июня 2014, 06:30:24
ilyar (http://umihelp.ru/forum/index.php?action=profile;u=543) и e.ioffe (http://umihelp.ru/forum/index.php?action=profile;u=37445) уже описали 2 наиболее подходящих варианта

1. вытягивать sql запрос ( $pages->query()) и модифицировав, получить ответ от базы данных.


2. сделать первоначальную выборку, получить список id и работать уже с ними в последующей выборке.

Хотелось бы добавить, что при первой выборке вы можете сократить нагрузку на систему запросив только id, вместо полных объектов\страниц.

Для этого в первой выборке добавьте параметр $pages->option('return', 'id');. В итоге, ваш первый selector будет выглядеть так:
$pages = new selector('pages');            
$pages->types('object-type')->id(121);
$pages->where('hierarchy')->page(6)->childs(3);
$pages->option('or-mode')->field('fieldname');
$pages->option('return', 'id');
$pages->where('fieldname')->equals('value');
$result = $pages->result();

затем формируем массив с id:
$ids_arr = array();
foreach($sel as $object) {
$ids_arr[] = $object['id'];;              
}

затем делаем новую выборку:
$final = new selector('pages'); 
$final->types('object-type')->id(121);
$final->where('id')->equals($mass);
//далее, пишите дополнительные условия.