Как отображать только записи с непустым полем meta_value?
Три человека уже пытались решить эту проблему, но безуспешно. Я хочу показывать только те записи, у которых есть значение в meta_key 'featured_image'.
То есть... если 'featured_image' не пустое, показать запись. Вот код:
<ul>
<?php
$args = array(
'showposts' => 5,
'meta_query' => array(
array(
'key' => 'featured_image',
'value' => '',
'compare' => '!='
)
)
);
$ft_pagination = new WP_Query( $args );
?>
<?php while ($ft_pagination->have_posts()) : $ft_pagination->the_post(); ?>
<?php $ftimage = get_post_meta(get_the_id(), 'featured_image', TRUE); ?>
<li>
<article>
<a href="">
<?php if ($ftimage): ?>
<img src="<?php bloginfo('template_directory'); ?>/timthumb.php?src=<?php echo $ftimage; ?>&w=84&h=60" alt="Изображение записи" title="Изображение записи" />
<?php else: ?>
<img src="<?php bloginfo('template_directory'); ?>/timthumb.php?src=/wp-content/themes/ssv/images/review-default.gif&w=84&h=60" alt="Изображение по умолчанию" title="Изображение по умолчанию" />
<?php endif; ?>
</a>
</article>
</li>
<?php
endwhile;
wp_reset_query();
?>
</ul>
Мы перепробовали буквально все возможные комбинации, включая устаревшие опции meta_*, query_posts, get_posts вместо WP_Query... Ничего не помогает. Вывели SQL-запрос, поле meta value не отображается. Оно существует - для записей (для каждой записи) и существует в базе данных.
Мы просмотрели все существующие публикации по этой теме, включая эти:
query_posts и отображение результатов только если пользовательское поле не пустое
http://scribu.net/wordpress/advanced-metadata-queries.html
Безрезультатно. Пожалуйста, помогите...

Похоже, это работает для передачи значения в запрос, но не уверен, возвращает ли он корректные результаты..
'meta_query' => array(
array(
'key' => 'some_key',
'value' => array(''),
'compare' => 'NOT IN'
)
)
Не было времени создавать поля для тестирования результатов, но я наблюдал за запросами, с которыми работал сегодня, и заметил, что NOT IN
спокойно принимает пустой массив.

Я знаю, что это старый ответ, но для тех, кто пробует этот подход, он работает с 'compare' => 'NOT LIKE'
вместо 'NOT IN
'

Наверное, более эффективно использовать != вместо not in или not like. То же самое, что и в http://wordpress.stackexchange.com/a/10286/32863 (там речь идет о meta keys, но принцип тот же)

Еще более чистое решение: как уже сказал Adam. Это использовать:
'value' => '',
'compare' => '!='

Это старый вопрос, но, похоже, WordPress исправил этот "недостающий функционал": теперь, согласно WordPress Codex, можно проверять наличие (или отсутствие) мета-ключа, вот так:
'meta_query' => array(
array(
'key' => 'featured_image',
'compare' => 'EXISTS', // или "NOT EXISTS" для проверки отсутствия ключа
)
)
Данная возможность доступна начиная с версии WordPress >= 3.5.

EXISTS
будет показывать пустые значения, что нам не подходит в данном случае. Лучшее решение, согласно моим тестам, это 'value' => '', 'compare' => '!='
.

@Ben Именно это и пробовал автор вопроса, но, судя по всему, без успеха. Я добавил свое решение, чтобы люди, которые ищут способ получить записи по наличию meta_key, могли его найти. Поскольку значение мета может быть "чем-то", "пустым" или "null" (если мета не существует), вероятно, лучшее решение - объединить два варианта с отношением "AND".

Этот запрос сработал у меня. Очень похоже на сравнение в ответе t31os от 2011 года, но поскольку ключ/значение метаданных — это простая текстовая строка, здесь не нужен массив meta_query.
$args = array(
'posts_per_page' => 5, // в версии 2.1 заменил 'showposts'
'meta_key' => 'featured_image',
'meta_value' => array(''),
'meta_compare' => 'NOT IN'
);
По какой-то причине использование 'meta_value' => ''
(установка пустой строки) и 'meta_compare' => '!='
или 'meta_compare' => 'NOT LIKE'
всё равно выводило все записи для меня, вероятно, это связано с тем, что я создал своё мета-значение с помощью плагина Advanced Custom Fields (ACF).
Хотя использование EXISTS
может работать, оно не проверяет, является ли значение пустым или нет, поэтому оно всё равно будет выводить записи, имеющие мета-поле, даже если значение метаданных пустое.
Подробнее о параметрах произвольных полей в кодексе. Возможные значения для meta_compare
:
=
!=
>
— работает с числовыми типами,DATE
иDATETIME
>=
— работает с числовыми типами,DATE
иDATETIME
<
— работает с числовыми типами,DATE
иDATETIME
<=
— работает с числовыми типами,DATE
иDATETIME
LIKE
— может работать с массивом мета-значенийNOT LIKE
— может работать с массивом мета-значенийIN
— мета-значение должно быть массивом значенийNOT IN
— мета-значение должно быть массивом значенийBETWEEN
— работает с числовыми типами,DATE
,DATETIME
, а также с массивом значенийNOT BETWEEN
— работает с числовыми типами,DATE
,DATETIME
, а также с массивом значенийEXISTS
— не требует указания мета-значения для версий WP 3.9 и вышеNOT EXISTS
— не требует указания мета-значения для версий WP 3.9 и вышеREGEXP
NOT REGEXP
RLIKE

Привет, @Rob:
Причина, по которой ты не можешь разобраться, как это сделать, заключается в том, что это невозможно, по крайней мере, без использования SQL. Попробуй добавить следующий код в файл functions.php
своей темы:
add_filter('posts_where','yoursite_posts_where',10,2);
function yoursite_posts_where($where,$query) {
global $wpdb;
$new_where = " TRIM(IFNULL({$wpdb->postmeta}.meta_value,''))<>'' ";
if (empty($where))
$where = $new_where;
else
$where = "{$where} AND {$new_where}";
return $where;
}
Если у тебя есть пользовательские поля 'featured_image'
с пустыми значениями, приведённый выше код отфильтрует их. Если твоя проблема в чём-то другом, нам нужно будет посмотреть на твои данные, чтобы решить её.
Мне интересно одно: как у тебя получились пустые значения для 'featured_image'
? Интерфейс админки в WordPress 3.1 всячески старается не допустить ввода пустых значений.
Надеюсь, это поможет.

Слава богу... значит, это не только у нас. Хорошо это знать, пожалуй. Спасибо, @MikeSchinkel - Они действительно должны добавить это в кодекс... Жду объяснения. Спасибо!!

@Rob - Так вот, я отталкивался от своих знаний по 3.0, а сейчас тестирую в 3.1, и вроде бы работает. У меня есть два поста, у одного есть пользовательское поле featured_image
, и ваш запрос работает нормально. Что у вас получается? Есть ли вероятность, что ваш запрос загружает посты, у которых есть поле featured_image
, но значение этого поля пустое?

@MikeSchinkel - Неужели? Да, именно это и происходит — у каждого поста есть поле featured_image, просто не у всех оно заполнено. Но загружаются все посты в любом случае.

@MikeSchinkel - Спасибо! Кажется, всё работает идеально после установки post_type в запросе. Пустые значения сделаны специально — не у каждой записи есть это изображение (и я знаю про миниатюры записей, просто они не подходят для этого сайта). Огромное спасибо!

@MikeSchinkel - Беру свои слова назад - запросы, для которых это нужно, работают, но на всех остальных страницах теперь выдает 404 ошибки. Страницы отдельных записей, архивы... :o\ Есть идеи?

В приведенном примере кода из вашего вопроса попробуйте поместить вызов add_filter()
непосредственно перед вызовом WP_Query()
, а затем добавьте remove_filter('posts_where','yoursite_posts_where');
прямо перед вызовом wp_reset_query()
.

Редактирование: из codex: $query = new WP_Query( 'meta_key=featured_image' );
смотрите здесь:http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters

Во-первых, вы всегда можете [редактировать] вопрос или ответ вместо добавления комментария. Во-вторых: не злоупотребляйте ответами вместо комментариев.

Если у вас новый вопрос, задайте его, нажав кнопку Задать вопрос. Включите ссылку на этот вопрос, если это поможет прояснить контекст.

@kaiser - мне кажется, он отвечал. Он не спрашивает, является ли его код валидным, а скорее саркастически отвечает на вопрос тем, что, по его мнению, сработает.

@kaiser, Комментарии предназначены для публикации ответов и кода? Как разместить код в комментарии?

@Nathan Я имел в виду саркастическую часть ответа. Код должен быть ответом — включая некоторое объяснение.

Это исправлено в WP 3.2-alpha:

Надеюсь, это поможет. Вы всегда можете использовать операторы сравнения 'EMPTY' (пусто) или 'NOT EMPTY' (не пусто) следующим образом:
'meta_query' => [
'relation' => 'AND',
[
'key' => 'your_key',
'compare' => 'NOT EMPTY',
],
]
Я использовал это с одним из моих чекбоксов ACF полей, и это отлично работает. В моем случае я делал противоположное тому, что делаете вы: некоторые посты в моем запросе не имели записи для этого мета-поля, поэтому я просто добавил опцию NOT EXISTS (не существует) в качестве второго условия сравнения.
Запрос постов, которые либо не содержат мета-поля, либо содержат пустое поле:
'meta_query' => [
'relation' => 'AND',
[
'key' => 'your_key',
'compare' => 'NOT EXISTS',
],
[
'key' => 'your_key',
'compare' => 'EMPTY',
],
]

У меня возникла конкретная проблема при использовании ACF (Advanced Custom Fields) и поля, которое содержало множественный выбор (multiple select), ранее заполненный, но теперь пустой.
Проблема была в том, что:
'relation' => 'AND',
array(
'key' => 'field_name',
'compare' => 'EXISTS'
),
array(
'key' => 'field_name',
'value' => '',
'compare' => '!='
),
Возвращало все записи, независимо от того, было ли мета-поле пустым или нет.
Вместо этого я решил проверить, содержит ли поле двойные кавычки:
'key' => 'field_name',
'value' => '"',
'compare' => 'LIKE'
Так как ACF использует двойные кавычки в структуре массива для множественных выборов, хранящихся в базе данных.
Надеюсь, это поможет тем, кто попал в ту же ловушку, что и я :-)
