Вопрос или проблема
Я создаю класс домов и хочу отфильтровать эти дома с помощью запроса. Но я не получаю никаких результатов:
Пример дома:
Минимальная цена: 10
Максимальная цена (поле не обязательно): пусто
У меня установлен фильтр цены на Минимальная цена 6 – Максимальная цена 15.
Я использую этот запрос, чтобы получить результаты, но он не работает.
new \WP_Query(
[
'post_type' => 'properties',
'meta_query' => [
'relation' => 'AND',
'min_price' => [
'relation' => 'AND',
[
'key' => 'min_price',
'value' => 6,
'compare' => '>=',
'type' => 'NUMERIC'
],
],
'max_price' => [
'relation' => 'AND',
[
'key' => 'max_price',
'value' => 11,
'compare' => '<=',
'type' => 'NUMERIC'
],
[
'key' => 'max_price',
'value' => '',
'compare' => '!=',
],
],
],
]
);
Мне также интересно, как сделать так, чтобы это работало с обязательным минимальным значением и необязательным максимальным значением. У меня такая же проблема с спальнями, ванными комнатами и т.д.
Заранее спасибо!
Это мой простой пример для тестирования, но он не работает. Минимальная цена не проблема, но когда я добавляю максимальную цену, это не работает.
'relation' => 'AND',
[
'key' => 'min_price',
'value' => 6,
'type' => 'NUMERIC',
'compare' => '>='
],
[
'key' => 'max_price',
'value' => 13,
'type' => 'NUMERIC',
'compare' => '<='
]
SQL ЗАПРОС
SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) WHERE 1=1 AND (
(
( wp_postmeta.meta_key = 'min_price' AND CAST(wp_postmeta.meta_value AS SIGNED) >= '6' )
AND
( mt1.meta_key = 'max_price' AND CAST(mt1.meta_value AS SIGNED) <= '13' )
)
) AND wp_posts.post_type="properties" AND (wp_posts.post_status="publish" OR wp_posts.post_status="acf-disabled") GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 999
Обновление ПРИЧИН
'relation' => 'OR',
[
'key' => 'min_price',
'value' => 6,
'type' => 'NUMERIC',
'compare' => '>='
],
[
'key' => 'max_price',
'type' => 'NUMERIC',
'value' => [6, 13],
'compare' => 'BETWEEN'
]
В зависимости от способа, которым ваш скрипт записывает max_price
, это на самом деле не является meta_key/meta_value в таблице postmeta
.
Вы пробовали изменить условие max_price на что-то вроде этого?
['max_price'] => [
'relation' => 'OR',
[
'key' => 'max_price',
'value' => 11,
'compare' => '<=',
],
[
'key' => 'max_price',
'compare' => 'NOT EXISTS',
],
],
Ответ или решение
Вопрос, который вы подняли, касается фильтрации объектов WordPress, используя класс WP_Query
, и в частности – корректной работы с метаполями min_price
и max_price
. Разберем основные моменты в вашем запросе и предложим возможные решения.
Проблема с фильтрацией запросов
При работе с метаполями важно помнить о логике SQL, которая используется под капотом WordPress. Вы упомянули, что у вас есть «минимальная цена» (min_price) и «максимальная цена» (max_price), причем max_price может быть пустым. При этом вы хотите получить все объекты, которые удовлетворяют условиям по этим метаполям.
Ваш изначальный запрос выглядит следующим образом:
new \WP_Query(
[
'post_type' => 'properties',
'meta_query' => [
'relation' => 'AND',
'min_price' => [
'relation' => 'AND',
[
'key' => 'min_price',
'value' => 6,
'compare' => '>=',
'type' => 'NUMERIC'
],
],
'max_price' => [
'relation' => 'AND',
[
'key' => 'max_price',
'value' => 11,
'compare' => '<=',
'type' => 'NUMERIC'
],
[
'key' => 'max_price',
'value' => '',
'compare' => '!=',
],
],
],
]
);
Ошибки и неполадки
- Логика
max_price
: В вашем запросе сmax_price
стоит использоватьOR
для проверки существования метаполя или его значения. - Настройка
meta_query
: Некоторые условия могут иметь конфликт, когда вы запрашиваете значения, которые могут существовать или отсутствовать.
Рекомендуемое решение
Вот как можно переписать ваш запрос для достижения ожидаемого результата:
new \WP_Query(
[
'post_type' => 'properties',
'meta_query' => [
'relation' => 'AND',
[
'key' => 'min_price',
'value' => 6,
'compare' => '>=',
'type' => 'NUMERIC'
],
[
'relation' => 'OR',
[
'key' => 'max_price',
'value' => 15,
'compare' => '<=',
'type' => 'NUMERIC'
],
[
'key' => 'max_price',
'compare' => 'NOT EXISTS' // или '!='
]
]
],
]
);
Объяснение кода
-
Родительская связь ‘AND’: SFСначала мы устанавливаем значение для
min_price
, которое обязательно для фильтрации. -
Вложенная связь ‘OR’: Проверяем два условия для
max_price
:- Сравнение значений, чтобы найти те записи, где
max_price
меньше или равно 15. - Проверяем, есть ли запись
max_price
вообще (предполагая, что поле может отсутствовать).
- Сравнение значений, чтобы найти те записи, где
Дополнительные соображения
Если у вас есть сведения о других атрибутах, таких как количество спален или ванных комнат, вы можете использовать аналогичную логику фильтрации. Всегда проверяйте наличие ваших метаполей и убедитесь, что они правильно настроены в базе данных.
Использование BETWEEN
может вызвать проблемы, если одно из значений в max_price
отсутствует. Убедитесь, что любые используемые значения соответствуют формату данных, чтобы избежать конфликта при фильтрации.
Заключение
Работа с WP_Query требует внимательного подхода к структуре запроса и логике фильтрации. Обязательно протестируйте все изменения, чтобы убедиться, что они возвращают ожидаемые результаты. Если у вас есть дальнейшие вопросы, не стесняйтесь их задавать!