Произвольные поля (или мета-данные) в WordPress позволяют добавлять дополнительную информацию к записям, страницам и пользовательским типам данных. Использовать произвольные поля можно в самых разных сценариях, например:
- для сайта недвижимости произвольными полями могут быть цена, площадь, координаты на карте
- для авто-каталога произвольными полями можно задавать мощность двигателя, цвет автомобиля, пробег
- для личного блога с помощью произвольных полей можно задать настроение, музыку или ваше место нахождения
Помимо сохранения и отображения произвольных полей, часто приходится искать, фильтровать и сортировать по этим полям. В этом нам помогут классы WP_Query
и WP_Meta_Query
.
Напоминаем вам, что WP_Query
это один из основных API в WordPress. Данный класс позволяет обращаться к базе данных WordPress и получать статьи, страницы и произвольные типы данных. В данной статье мы рассмотрим параметры к классу WP_Query
, которые отвечают за работу с мета-данными.
Параметр meta_query
Основным параметром для работы с мета-данными в WP_Query
является meta_query
, который реализован классом WP_Meta_Query
. Параметр meta_query
— это массив, где каждый элемент является в свою очередь массивом с параметрами мета-запроса. Рассмотрим простой пример:
$query = new WP_Query( array( 'post_type' => 'post', 'meta_query' => array( array( 'key' => 'mood', 'value' => 'happy', ), ), ) );
Если вы не знакомы с параметром post_type
и другими параметрами WP_Query
, советуем обратиться к нашей статье.
Как видно из примера, meta_query
содержит массив с одним элементом, который указывает ключ и значение произвольного поля с помощью key
и value
. Данный пример вернет записи, которые мы опубликовали в хорошем настроении.
Каждый массив в meta_query
может содержать следующие элементы:
key
— это ключ (или имя) нашего произвольного поляvalue
— значение произвольного поля, строкой или массивомcompare
— тип сравнения, например:=
,!=
,>
,>=
,<
,<=
,LIKE
,NOT LIKE
,IN
,NOT IN
,BETWEEN
,NOT BETWEEN
,EXISTS
,NOT EXISTS
type
— тип значения, например:NUMERIC
,BINARY
,CHAR
,DATE
,DATETIME
,DECIMAL
,SIGNED
,TIME
,UNSIGNED
Рассмотрим еще один пример с использованием чисел и другого типа сравнения:
$query = new WP_Query( array( 'post_type' => 'property', 'meta_query' => array( array( 'key' => 'price', 'value' => 50000, 'compare' => '<=', 'type' => 'NUMERIC', ), ), ) );
Здесь мы запрашиваем у WP_Query
записи произвольного типа property
, где значение произвольного поля price
меньше или равно 50,000.
Важно отметить, что все значения произвольных полей в WordPress имеют текстовый тип, а значение параметра type
позволяет преобразовать все значения в требуемый тип перед сравнением. В нашем случае это число (NUMERIC
).
Несколько запросов meta_query
Как мы уже упомянули, параметр meta_query
является массивом массивов, что позволяет легко указать более одного запроса или условия. Например:
$query = new WP_Query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => 'color', 'value' => 'red', ), array( 'key' => 'size', 'value' => 'XL', ), ), ) );
Данный запрос вернет записи типа product
у которых в произвольных полях указан красный цвет и размер XL. По умолчанию в meta_query
запросы будут производиться с оператором "и", а не "или", но это легко изменить с помощью аргумента relation
:
$query = new WP_Query( array( 'post_type' => 'product', 'relation' => 'OR', 'meta_query' => array( array( 'key' => 'color', 'value' => 'red', ), array( 'key' => 'color', 'value' => 'blue', ), ), ) );
В данном примере мы получим продукты красного или синего цвета. Когда речь идет об одном ключе и нескольких возможных значениях, подобный запрос написать гораздо проще (и быстрее) с помощью сравнения типа IN
:
$query = new WP_Query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => 'color', 'value' => array( 'red', 'blue' ), 'compare' => 'IN', ), ), ) );
Сортировка с помощью произвольного поля
Часто при работе с мета-данными в WordPress приходится учитывать их при сортировке результатов. За это в классе WP_Query
отвечает параметр orderby
, где можно указать:
meta_value
- сортировать по значению мета-поляmeta_value_num
- сортировать по численному значению мета-поля- для сортировки по дате, заголовку и другим полям см. нашу статью
При использовании значений для сортировки по произвольным полям необходимо в параметрах к WP_Query
так же указать ключ для сортировки с помощью аргумента meta_key
. Простой пример вывода автомобилей по их цене по возрастанию:
$query = new WP_Query( array( 'post_type' => 'auto', 'meta_key' => 'price', 'orderby' => 'meta_value_num', 'order' => 'ASC', ) );
Более сложный пример: вывод красных автомобилей мощностью от 100 до 150 лошадиных сил, и сортировка по цене по убыванию:
$query = new WP_Query( array( 'post_type' => 'auto', 'meta_query' => array( array( 'key' => 'color', 'value' => 'red', ), array( 'key' => 'hp', 'value' => array( 100, 150 ), 'compare' => 'BETWEEN', 'type' => 'NUMERIC', ), ), 'meta_key' => 'price', 'orderby' => 'meta_value_num', 'order' => 'DESC', ) );
Производительность meta_query
Параметр meta_query
действительно позволяет делать многое с произвольными полями в WordPress, но не стоит забывать о производительности, особенно если речь идет о большом количестве данных и о сложных запросах с мета-полями.
Поле meta_value
таблицы wp_postmeta
в базе данных MySQL не имеет индекса из-за его типа LONGTEXT
. Но даже если бы был индекс, пользы от него было бы мало, поскольку запросы с meta_query
используют MySQL функцию CAST
для перевода типа данных при поиске, а присутствие подобной функции в запросе значит, что индекс использован не будет.
Иными словами, всегда проверяйте ваши запросы на реальной базе данных, измеряйте время их выполнения и зависимость этого времени от количества записей и параметров запроса. Если ваши запросы стали слишком медленными, возможно настало время подключать внешнюю систему индексирования и поиска, например Sphinx или Elasticsearch.
Если у вас остались вопросы по работе с произвольными полями в WP_Query
, оставьте комментарий и мы обязательно вам ответим.