отримання всіх значень для користувацького ключа поля (перехресний пост)


44

Я знаю, як отримати значення спеціального поля для конкретної публікації.

get_post_meta($post_id, $key, $single);

Що мені потрібно - це отримати всі значення, пов’язані з певним користувацьким ключем, для всіх публікацій .

Хтось знає про ефективний спосіб зробити це? Я не хотів би переглядати всі ідентифікатори повідомлення в БД.

Приклад:

4 публікації з різними значеннями для користувацького поля під назвою "Настрій". 2 повідомлення мають значення "щасливий", 1 допис - "сердитий", а 1 повідомлення "сумний"

Я хочу вивести: в усіх публікаціях, які ми маємо: два щасливих, один сердитий і один сумний автор.

Але для багато публікацій.

Що я шукаю:

  • функція WP, щоб отримати це. або
  • спеціальний запит, щоб отримати це максимально ефективно.

5
Здається, ви використовуєте це як систематику. Чому б не просто (автоматично) додати термін до цих публікацій під час збереження? Зробив би запит набагато простіше.
кайзер

@kaiser Я не можу подякувати тобі за те, що ти геній!
користувач2128576

Відповіді:


58

Одним із можливих підходів було б використання одного з допоміжних методів у класі WPDB для виконання більш вдосконаленого мета-запиту. Але застереження щодо використання деяких з цих функцій полягає в тому, що зазвичай не отримують простий масив даних і зазвичай доводиться робити непотрібні посилання на властивості об'єкта, навіть якщо ви викликаєте лише один стовпець або рядок.

Звичайно, не всі функції є одними і тими ж, і цілеспрямована згадка виходить до методу WPDB , get_colякий повертає простий плоский масив запитуваних даних, я зазначаю саме цю згадку, тому що наступний приклад зажадає цей метод .

WordPress - WPDB Вибір стовпця даних
$ wpdb-> get_col ()

Ось приклад функції, яка запитує базу даних для всіх постів вибраного типу публікації, статусу публікації та з певним мета-ключем (або спеціальним полем для менш технічно налаштованих).

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

Так, наприклад, якщо ви хочете дізнатися, які публікації мають мета-ключ рейтингу , для фільмів про тип публікацій, і ви хочете зберігати цю інформацію всередині змінної, прикладом такого дзвінка може бути ..

$movie_ratings = get_meta_values( 'rating', 'movies' );

Якщо ви хотіли нічого більше, ніж надрукувати ці дані на екран, функція імплодизації PHP може швидко сплавити цей простий масив у рядки даних.

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

Ви також можете використовувати повернуті дані, щоб визначити, скільки публікацій мають ці мета-значення, виконавши простий цикл над поверненими даними та побудувавши, наприклад, масив підрахунків.

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

Ця логіка може бути застосована до різного роду даних і розширена для роботи будь-якою кількістю різних способів. Тож я сподіваюся, що мої приклади були корисними та простими для наслідування.


3
Також цікавий факт для майбутніх глядачів, якщо ви хочете витягнути лише унікальні мета-значення - ви вводите DISTINCTвідразу після SELECTфункції вгорі. Може бути корисним.
Howdy_McGee

Я вважаю, що це надзвичайно корисно
Pablo SG Pacheco

Як це зробити і повернути відсортовані значення? Я думаю, що за допомогою ORDER, але я не можу зрозуміти, як це використовувати
efirvida

14

Я просто хотів би додати одну крихітку до коду t31os вище. Я змінив "SELECT" на "SELECT DISTINCT", щоб усунути повторювані записи, коли я сам використовував цей код.


1
Я можу уявити випадки, коли було б дійсно мати декілька мета-значень одного і того ж значення, і, отже, не вносило цього доповнення до свого коду. Якщо ви хочете чітких значень, це був би шлях. Крім того, ви можете також додати це як аргумент для функції (так що ви можете використовувати її чи ні, якщо потрібно).
t31os

10

Недоцільно або потрібно використовувати глобальний $ wpdb:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );

У більшості випадків це мій кращий спосіб зробити це. Він робить п'ять запитів, а не лише один, але, оскільки він використовує стандартні процедури WordPress для створення та подання їх, будь-яке кешування для певної платформи (наприклад, кешування об'єктів WP Engine або якийсь випадковий плагін) запускається. Дані також зберігатимуться у внутрішньому кеш-пам'яті WordPress протягом тривалості запиту, тому його не потрібно буде знову отримувати з бази даних, якщо потрібно.
Ендрю Дінмор

До даних також застосовуватимуться будь-які фільтри, що може бути надзвичайно важливим, наприклад, на багатомовному сайті. Нарешті, оскільки він використовує лише стандартні основні функції WordPress, це набагато рідше буде порушено майбутнім оновленням.
Ендрю Дінмор

4

найшвидший спосіб - це користувацький запит sql, і я не впевнений, але ви можете спробувати

$wpdb->get_results("
  SELECT posts.* , COUNT(*) 'moodcount'
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'Mood'
  GROUP BY postmeta.meta_key
");

Якщо що, то це його початок.


1
дякую, але чи не слід уникати користувацьких питань "за будь-яку ціну"? Я вважаю за краще використовувати шар абстракції WP (це, як це називається?) ... але, звичайно, якщо це неможливо ..
mikkelbreum

Спеціальні запити, якщо вони написані правильним способом, можуть бути кращими, і вам слід уникати їх, лише якщо ви не знаєте, що робите.
Bainternet

1
Я погоджуюся з mwb .custom-запитами дуже корисні та практичні, але я думаю, що вони також набагато важчі для БД .. особливо з використанням функцій SRT ..
krembo99

3

Для отримання всіх мета-значень мета-ключем

Перевірте wp-> db wordpress codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );

3
Проблема такого підходу полягає у відсутності специфіки. Ви отримаєте численні результати від такого запиту, який може включати в себе чернетки, перенесені елементи, публікації, сторінки та будь-який інший тип публікації. Ніколи не слід запитувати те, що вам не потрібно, тут, безумовно, потрібна специфіка.
t31о

Хоча це правда, що ви могли отримати значення з інших типів та статусів публікацій, бувають випадки, коли все, що вам потрібно, - це ці значення, і ви не використовували цей мета-ключ ніде, але там, де вам це потрібно. Якщо всі / більшість значень унікальні, це може бути найкращим рішенням.
Люк Гедеон

2

Немає причин, чому ви не можете об'єднати t31os і код Bainternet, щоб мати готовий повторний вигляд (стиль wordpress), який повертає кількість і значення за одну ефективну операцію.

Це власний запит, але він все ще використовує шар абстракції бази даних Wordpress - так, наприклад, не має значення, якими насправді є назви таблиць, або якщо вони змінюються, і це підготовлене твердження, тому ми набагато безпечніші від атак SQL тощо .

У цьому випадку я більше не перевіряю тип публікації і виключаю порожні рядки:

    $r = $wpdb->get_results(  $wpdb->prepare( "
        SELECT pm.meta_value AS name, count(*) AS count  FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s'
        AND pm.meta_value != '' 
        AND p.post_type = '%s'
        GROUP BY pm.meta_value
        ORDER BY pm.meta_value          
        ", $key, $type) 
        );
    return $r;

У цьому конкретно є

Це поверне масив таких об’єктів:

array  
 0 => 
 object(stdClass)[359]
  public 'name' => string 'Hamish' (length=6)
  public 'count' => string '3' (length=1)
 1 => 
 object(stdClass)[360]
  public 'name' => string 'Ida' (length=11)
  public 'count' => string '1' (length=1)
 2 => 
 object(stdClass)[361]
  public 'name' => string 'John' (length=12)
  public 'count' => string '1' (length=1)

0

Використовуйте наступне з foreach

 $key = get_post_custom_values( 'key' );

Передбачає, що назва вашого спеціального поля поля є


Зауважте, що це значення за замовчуванням для поточної публікації, коли не вказано post_id.
birgire
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.