Получение записей на основе meta key/value

4 июн. 2013 г., 12:28:26
Просмотры: 25.4K
Голосов: 6

У меня есть произвольный тип записи "custom_author", который выбирается при создании новой записи с помощью выпадающего списка metabox с ключом поля "chosen_author".

Вот как выглядит моя таблица wp_postmeta:

Пример структуры таблицы wp_postmeta с мета-данными

Где 13088 - это запись блога, которой назначен "автор" 13112.

Я пытаюсь получить все записи определенного автора, используя следующий код:

$args = array(
        'post_type'     => 'post',
        'post_status'   => 'publish',
        'meta_query' => array(
            array(
                'key' => 'chosen_author',
                'value' => '13112' // пробовал с кавычками и без
            )
        )
    );

    $getPosts = new WP_Query($args);

Но он возвращает ВСЕ мои записи.

Я сделал некоторую отладку:

$getPosts = new WP_Query($args);
echo $GLOBALS['wp_query']->request;

и получил следующий вывод:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND (wp_posts.post_author != 0) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10

Полностью игнорируется массив meta_query!

Если это важно, код используется вне цикла

2
Комментарии

$GLOBALS['wp_query']->request не будет вашим запросом, поскольку ваш запрос не является $wp_query, глобальным или каким-либо другим, это $getPosts. Вам нужно использовать echo $getPosts->request.

s_ha_dum s_ha_dum
4 июн. 2013 г. 18:07:42

Если вы сохраняете $getPosts, почему бы просто не использовать $getPosts->posts?

->request содержит REQUEST, то есть SQL-запрос для ваших записей, а не РЕЗУЛЬТАТЫ... :)

jave.web jave.web
12 июн. 2017 г. 10:02:36
Все ответы на вопрос 2
7

Проблема

Похоже, что вы сохраняете данные так:

$a = array( "13112" );
update_post_meta( $post_id, "article_author", $a);

что приведёт к следующему значению meta_value:

a:1:{i:0;s:5:"13112";}

Ваш первый запрос даст экранированные кавычки:

LIKE '%\"13112\"%'

Способ 1

Если сохранить массив авторов с числами вместо строк:

$a = array( 13112 );
update_post_meta( $post_id, "article_author", $a);

то соответствующее значение meta_value будет

a:1:{i:0;i:13112;}

Тогда при использовании мета-запроса:

 'meta_query' => array(
            array(
                'key' => 'article_author',
                'value' => ':13112;',
                'compare' => 'LIKE'
            )
    )

соответствующая часть SQL будет

LIKE '%:13112;%'

Вы можете попробовать использовать этот вариант.

Способ 2

Другой способ — заменить экранированные кавычки на обычные:

add_filter('posts_where','my_posts_where');
$getPosts = new WP_Query($args);
remove_filter('posts_where','my_posts_where');

где

function my_posts_where($where){    
    $where = str_replace('\"', '"', $where);    
    return $where;  
}

но я не рекомендую этот метод.

4 июн. 2013 г. 13:46:39
Комментарии

Спасибо за это, у меня не так много контроля над форматом сохранения (строка/число). Интересно, почему возвращаются все записи, если явно не найдено совпадение? Как я должен обрабатывать ситуацию, когда нет совпадающих записей, если возвращаются все мои записи? Примечание: ОК, это не ВСЕ записи, но возвращаются сотни.

Titan Titan
4 июн. 2013 г. 14:18:04

Да, это странно, когда вы ищете в PHPMyAdmin, вы получаете аналогичные результаты?

birgire birgire
4 июн. 2013 г. 14:48:34

Я использовал плагин для работы с пользовательскими метабоксами (выпадающий список записей моего пользовательского типа). Затем я разобрался и реализовал все самостоятельно в functions.php, и теперь сохраняю в базе данных только число как meta_value: 13112. Но все равно безрезультатно. Попробую включить какой-нибудь режим отладки, который выводит SQL-запрос, который он пытается выполнить.

Titan Titan
4 июн. 2013 г. 17:09:26

Странно, я использовал $GLOBALS['wp_query']->request; чтобы проверить, и он вывел SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND (wp_posts.post_author != 0) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10, полностью игнорируя meta_query!!

Titan Titan
4 июн. 2013 г. 17:15:26

Я обновил свой первоначальный вопрос более актуальной сводкой

Titan Titan
4 июн. 2013 г. 17:20:28

Исправлено ниже (извините за спам!)

Titan Titan
4 июн. 2013 г. 17:36:26

Хорошо, рад слышать, что вы нашли обходное решение вашей проблемы ;-) Вам следует проверить ваш SQL с помощью $getPosts->request вместо этого.

birgire birgire
4 июн. 2013 г. 17:51:54
Показать остальные 2 комментариев
0

Исправлено с использованием

get_posts($args) вместо new WP_Query($args);

Не знаю почему...

4 июн. 2013 г. 17:36:00