Рейтинг: 0  
На голосовании
Предложил Голубева Марина 01.02.2019 08:37:47

Проверка вхождения строки в фильтре GetList

$arSelect = Array("ID", "IBLOCK_ID", "NAME", "DETAIL_PAGE_URL", "PREVIEW_PICTURE", "DETAIL_PICTURE", "CATALOG_GROUP_7", "PROPERTY_CML2_ARTICLE");
$arFilter = Array("IBLOCK_ID"=>$GLOBALS['CATALOG_IBLOCK_ID'],
"ACTIVE"=>"Y",
      "ACTIVE_DATE"=>"Y",
      "?PROPERTY_CML2_ARTICLE"=>$acat,);

$res = CIBlockElement::GetList(Array(),$arFilter,false,false,$arSelect);

Предложение касается строки фильтра: "?PROPERTY_CML2_ARTICLE"=>$acat
При помощи этого фильтра отфильтруются элементы, у которых $acat является подстрокой строки "PROPERTY_CML2_ARTICLE".

А отфильтровать в другом направлении, чтобы значения "PROPERTY_CML2_ARTICLE" могли быть подстроками $acat невозможно.

Предлагаю добавить эту возможность.
Рейтинг: 0  
На голосовании
Предложил Артем Артемов 28.02.2018 20:45:27

Дополнительный LIMIT в CIBlockElement::GetList

В нестандартных случаях (например, написание API) очень часто требуется обычный лимит, как используется базах данных, например, вот так:
SEL ECT * 
FR OM  `b_iblock_element` 
LIMIT 30 , 30
Чтобы сделать такую возможность для разработчиков, впринципе, достаточно заменить код:
if (!empty( $arNavStartParams ) && is_array ( $arNavStartParams )) {
следующим
if (!empty($arNavStartParams['limitStart']) && !empty($arNavStartParams['limitCount'])){
    $strSql = "
        SELECT ".$el->sSelect."
        FR OM ".$el->sFrom."
        WH ERE 1=1 ".$el->sWhere."
        ".$el->sGroupBy."
        ".$el->sOrderBy."
        LIMIT ".intval ($arNavStartParams['limitStart']).", ".intval ($arNavStartParams['limitCount'])."
    ";
    $res = $DB->Query ( $strSql,
                        false,
                        "FILE: ".__FILE__."<br> LINE: ".__LINE__
    );
} elseif (!empty( $arNavStartParams ) && is_array ( $arNavStartParams )) {

ну и дополнить документацию https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php
Рейтинг: 42.864  
Внедрено
Предложил Плотников Александр 11.08.2014 11:55:30

Релевантный поиск по каталогу. Компонент catalog.search

Сейчас нет возможности получить релевантный результат поиска по каталогу, если использовать компонент catalog.search. Т.е. пользователь при поиске по запросу "Мясо" может получит несколько страниц с товарами, где есть в описание слова "Мясо", а потом уж сам товар с название "Мясо".

Почему так происходит?
 Своей особой логики по сути у компонента  catalog.search в файле component.php нету. Шаблон компонент состоит из search.page в связке с catalog.section. search.page формирует массив $arElements состоящий из ID элементов отсортированных по релевантности и передает в catalog.section.

Проблема состоит в том, что catalog.section сортирует массив данных по своим правилам из параметров ELEMENT_SORT_FIELD и ELEMENT_SORT_FIELD2, где исходная сортировка не учитывается. Корректная сортировка  данных в result_modifier.php возможно только, когда нету разбиения на страницы данных.

Если посмотреть компонент catalog.section, то он основан на CIBlockElement::GetList функции.

Чтобы решить проблему нужно добавить в новый тип сортировки (на пример default)  в функции CIBlockElement::GetList, чтобы получить релевантный поиск, т.е. чтобы входной массив ID элементов и задав сортировку элементов.
Или переработать этот компонент, чтобы была возможность получить релевантные данные поиска.
Рейтинг: 0  
Ответил Жуков Евгений 23.07.2019 15:42:55
Выйдет в iblock 19.0.0. Возможен сдвиг обновления.
Рейтинг: 6.0121  
Внедрено
Предложил Кирсанов Анатолий 15.05.2014 16:26:52

Добавить в CIBlockElement::GetList наравне с CATALOG_QUANTITY выборку CATALOG_QUANTITY_RESERVED

Сейчас (инфоблоки 14.5.3, каталог 14.5.3) этот метод выбирает много о товаре вместе с элементом инфоблока, но не количество зарезервированного товара. Приходится делать дополнительную выборку на основе CCatalogProduct::GetList. При наличии двух выборок, соединение в CIBlockElement::GetList с таблицей товаров уже не имеет смысла, раз все равно собирать данные о товаре отдельным вызовом.

Предлагаю дополнить выборку данных о товаре еще одним полем. Я проверил исходники - сложность в реализации не выше, чем для уже существующего в выборке CATALOG_QUANTITY (это два поля одной таблицы).

Данное усовершенствование API особенно сильно требуется в скриптах по обмену остатками (с 1С или другими системами учета товаров). Несмотря на развитие интеграции с 1С свои скрипты будут работать еще годы, т.к. конфигурации 1С поднять до нужного уровня очень сложно.

Предложил сначала в поддержке, получил предложение-отписку насчет сайта идей. Обращение 487565.
Рейтинг: 0.1389  
Ответил Жуков Евгений 20.05.2014 17:30:33
Выйдет в catalog 14.5.5

P.S. В нашем коде мы уходим от использования CIBlockElement для получения инфомации о товаре как таковом.
Рейтинг: 1.5505  
Новая
Предложил Карабаев Виктор 30.03.2013 19:18:30

Управлять работой CIBlockElement::GetList

Имеется некая база данных. Имеется следующий код:


$arSel ect2 = Array("ID", "NAME", "PROPERTY_USER", "PROPERTY_ZAKAZ", "PROPERTY_CAT_ID", "PROPERTY_CAT_ARTICUL", "PROPERTY_CAT_MANUF", "PROPERTY_CAT_NAME", "PROPERTY_CAT_SUPPLIER", "PROPERTY_CAT_DATE", "PROPERTY_CAT_PRICE", "PROPERTY_CAT_QUANT";);
$arFilter2 = Array("IBLOCK_ID"=>$IBLOCK, "ACTIVE_DATE"=>"Y", "ACTIVE"=>"Y", "PROPERTY_USER"=>$_REQUEST["uid"], "!PROPERTY_ZAKAZ"=>5, "SECTION_ID"=>$_REQUEST["sid"]);
$res2 = CIBlockElement::GetList(Array(), $arFilter2, false, Array(), $arSelect2);
while($ob2 = $res2->GetNextElement()) {
 $arFields2 = $ob2->GetFields();    
}


На данный момент вот в данном инфоблоке, находится всего два элемента. Вообще в базе, около 4000 элементов, с разными свойствами. Сервер - отдельный физический сервер. Centos6. Веб окружение Битрикс с оптимальными конфигурационными файлами.

Время выполнения кода выше - 33 секунды.

Проблема:

SELECT COUNT('x') as C
FR OM
b_iblock B
INNER JOIN b_lang L ON B.LID=L.LID
INNER JOIN b_iblock_element BE ON BE.IBLOCK_ID = B.ID
INNER JOIN b_iblock_property FP0 ON FP0.IBLOCK_ID = B.ID AND FP0.CODE='USER'
LEFT JOIN b_iblock_property FP1 ON FP1.IBLOCK_ID = B.ID AND FP1.CODE='ZAKAZ'
LEFT JOIN b_iblock_property FP2 ON FP2.IBLOCK_ID = B.ID AND FP2.CODE='CAT_ID'
LEFT JOIN b_iblock_property FP3 ON FP3.IBLOCK_ID = B.ID AND FP3.CODE='CAT_ARTICUL'
LEFT JOIN b_iblock_property FP4 ON FP4.IBLOCK_ID = B.ID AND FP4.CODE='CAT_MANUF'
LEFT JOIN b_iblock_property FP5 ON FP5.IBLOCK_ID = B.ID AND FP5.CODE='CAT_NAME'
LEFT JOIN b_iblock_property FP6 ON FP6.IBLOCK_ID = B.ID AND FP6.CODE='CAT_SUPPLIER'
LEFT JOIN b_iblock_property FP7 ON FP7.IBLOCK_ID = B.ID AND FP7.CODE='CAT_DATE'
LEFT JOIN b_iblock_property FP8 ON FP8.IBLOCK_ID = B.ID AND FP8.CODE='CAT_PRICE'
LEFT JOIN b_iblock_property FP9 ON FP9.IBLOCK_ID = B.ID AND FP9.CODE='CAT_QUANT'
INNER JOIN b_iblock_element_property FPV0 ON FPV0.IBLOCK_PROPERTY_ID = FP0.ID AND FPV0.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV1 ON FPV1.IBLOCK_PROPERTY_ID = FP1.ID AND FPV1.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV2 ON FPV2.IBLOCK_PROPERTY_ID = FP2.ID AND FPV2.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV3 ON FPV3.IBLOCK_PROPERTY_ID = FP3.ID AND FPV3.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV4 ON FPV4.IBLOCK_PROPERTY_ID = FP4.ID AND FPV4.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV5 ON FPV5.IBLOCK_PROPERTY_ID = FP5.ID AND FPV5.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV6 ON FPV6.IBLOCK_PROPERTY_ID = FP6.ID AND FPV6.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV7 ON FPV7.IBLOCK_PROPERTY_ID = FP7.ID AND FPV7.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV8 ON FPV8.IBLOCK_PROPERTY_ID = FP8.ID AND FPV8.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_element_property FPV9 ON FPV9.IBLOCK_PROPERTY_ID = FP9.ID AND FPV9.IBLOCK_ELEMENT_ID = BE.ID
LEFT JOIN b_iblock_property_enum FPEN0 ON FPEN0.PROPERTY_ID = FPV1.IBLOCK_PROPERTY_ID AND FPV1.VALUE_ENUM = FPEN0.ID
INNER JOIN ( SELECT DISTINCT BSE.IBLOCK_ELEMENT_ID
FR OM
b_iblock_section_element BSE
INNER JOIN b_iblock_section BS ON BSE.IBLOCK_SECTION_ID = BS.ID
WHERE
((BS.ID IN (3700))) ) BES ON BES.IBLOCK_ELEMENT_ID = BE.ID
WH ERE
1=1 AND ( ((((BE.IBLOCK_ID = '12')))) AND (((BE.ACTIVE_TO >= now() OR BE.ACTIVE_TO IS NULL) AND (BE.ACTIVE_FROM <= now() OR BE.ACTIVE_FROM IS NULL))) AND ((((BE.ACTIVE='Y')))) AND ((((FPV0.VALUE LIKE '1')))) AND ((( FPV1.VALUE_ENUM IS NULL OR NOT (FPV1.VALUE_ENUM = '5')))) ) AND (((BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL)))    


Этот запрос занимает всё время. И результат его работы - просто подсчет количества элементов...

ЗАЧЕМ????

Мне НЕ нужно в данном случае считать элементы! ПОЧЕМУ нельзя или обойтись без этого запроса совсем, или сделать некую переменную через которую управлять подсчетом??? Передана функции переменная - посчитали. Нет - ничего не считаем.

Проблема имеет общий характер.

Обобщая это звучит так:

Если вы используете функцию CIBlockElement::GetList, вам нужно сделать выборку из инфоблока с большим количеством свойств, и нужно выбрать эти свойства, производительность падает фатально. И чем больше размер у вас бд, тем хуже и фатальней результат.