Выборки из инфоблоков - старое ядро и D7 на практике
Выборки - подтема на 23 вопроса из собранных. Почти все они об одном: как достать нужные элементы одним запросом, а не циклом.
Что общего у этих задач
В платформе живут два API выборки. Старое ядро отдаёт результат объектом с методом получения строк, новое - объектом запроса с полями и соединениями. Оба работают, оба поддерживаются, и выбор между ними чаще определяется тем, что нужно достать, а не годом написания кода.
Свойства элементов лежат не в той же таблице. Старое ядро прячет это за
именами полей вида PROPERTY_CODE_VALUE, новое требует соединения явно. Отсюда
разница в поведении: там, где старый вызов молча делает лишний запрос, новый
заставляет описать связь руками.
Разделы элемента - отдельная связь. Элемент принадлежит нескольким разделам, и «раздел элемента» в выборке означает основную привязку. Полный список разделов приходит только через таблицу связи, и цикл по элементам здесь не нужен.
Выборка стоит денег на каждой странице. Лишние поля, запрос в цикле и отсутствие кэша не видны на сотне элементов и становятся заметны на десятках тысяч.
Решения подтемы
- Выборки из инфоблоков: GetList, ORM и разделы - два API, свойства и разделы, ограничение выборки, лишние запросы.
- Кэширование своей выборки: ключ, теги, сброс - обёртка вокруг запроса, состав ключа, теги.
- Постраничная навигация: страницы в выборке, свой вызов, кэш - размер страницы, вывод ссылок, два списка, кэш.
- Инфоблок через ORM: API_CODE, класс элементов, свойства - код для интерфейса, класс сущности, свойства и списки.
- Элемент не появляется в списке: разбор причин - активность и даты, раздел, права, кэш, фильтр.
- Сложный фильтр выборки: ИЛИ, вложенные условия, подзапросы - группы условий, вложенность, подзапрос, проверка запроса.
- Постраничная навигация сбоит: разбор причин - повторы и пустые страницы, сортировка, соединения, кэш и адрес.
- Запись в инфоблок через ORM: побочные эффекты старого ядра - поиск и фасеты, ресайз картинок, дерево разделов, SEO-шаблоны, события.
Частые вопросы
Что использовать в новом коде - GetList или ORM?
Для простых выборок разницы почти нет. ORM выигрывает там, где нужны соединения, свои поля в выборке и предсказуемый SQL, а старое ядро - там, где нужны вычисляемые поля вроде адреса элемента.
Как ограничить число элементов в выборке?
В старом ядре - через параметры постраничной навигации, в ORM - методом ограничения количества. Простого параметра «сколько строк» у старого GetList нет.
Почему выборка делает сотни запросов?
Значения свойств и разделы дочитываются на каждой строке отдельно. Их запрашивают сразу в выборке либо получают одним запросом по списку идентификаторов.
Как получить все разделы элемента?
Через таблицу связи элементов и разделов. Поле раздела в самом элементе хранит только основную привязку, по которой строится адрес.
Связанные темы
- Инфоблоки - устройство хранилища целиком
- Свойства инфоблоков - откуда берутся значения свойств
- D7 ORM - как устроен новый слой доступа к данным
- Раздел Инфоблоки и данные