Abrufen aller Werte für einen benutzerdefinierten Feldschlüssel (Cross-Post)

44

Ich weiß, wie ich einen benutzerdefinierten Feldwert für einen bestimmten Beitrag erhalte.

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

Was ich brauche, ist, alle Werte, die mit einem bestimmten benutzerdefinierten Beitragsschlüssel verknüpft sind, über alle Beiträge hinweg abzurufen .

Kennt jemand einen effizienten Weg, dies zu tun? Ich möchte nicht alle Post-IDs in der DB durchlaufen.

Beispiel:

4 Posts mit unterschiedlichen Werten für ein benutzerdefiniertes Feld namens "Stimmung". 2 Beiträge haben den Wert 'glücklich', 1 Beitrag hat 'wütend' und 1 Beitrag hat 'traurig'

Ich möchte Folgendes ausgeben: über alle Posts, die wir haben: zwei glückliche, eine wütende und eine traurige Autor (en).

Aber für viele Beiträge.

Was ich suche, ist entweder:

  • eine WP Funktion um dies zu bekommen. oder
  • eine benutzerdefinierte Abfrage, um dies so effizient wie möglich zu erhalten.
mikkelbreum
quelle
5
Scheint, als ob Sie dies als Taxonomie verwenden. Warum nicht einfach (automatisch) beim Speichern einen Begriff zu diesen Beiträgen hinzufügen? Würde das Abfragen viel einfacher machen.
Kaiser
@kaiser Ich kann dir gar nicht genug dafür danken, dass du ein Genie bist!
User2128576

Antworten:

58

Ein möglicher Ansatz wäre, eine der Hilfsmethoden in der WPDB-Klasse zu verwenden, um eine verfeinerte metabasierte Abfrage durchzuführen. Die Einschränkung bei der Verwendung einiger dieser Funktionen besteht jedoch darin, dass Sie normalerweise kein einfaches Array von Daten zurückerhalten und in der Regel unnötige Verweise auf Objekteigenschaften erstellen müssen, selbst wenn Sie nur eine Spalte oder Zeile aufrufen.

Natürlich sind nicht alle Funktionen gleich, und die WPDB- Methode, get_coldie ein einfaches, flaches Array der abgefragten Daten zurückgibt , wird absichtlich erwähnt. Ich erwähne dies ausdrücklich, weil das folgende Beispiel diese Methode aufruft .

WordPress - WPDB Auswahl einer
Datenspalte $ wpdb-> get_col ()

Hier ist eine Beispielfunktion, die die Datenbank nach allen Beiträgen eines ausgewählten Beitragstyps, Beitragsstatus und mit einem bestimmten Metaschlüssel (oder benutzerdefinierten Feld für weniger technisch denkende) abfragt.

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;
}

So zum Beispiel, wenn Sie welche Beiträge , um herauszufinden , wie ein Meta - Schlüssel haben Bewertung , für die Post - Art Filme und Sie möchten , dass innerhalb einer Variablen , die Informationen speichern, ein Beispiel für eine solche Aufforderung wäre ..

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

Wenn Sie nichts weiter tun wollten, als diese Daten auf dem Bildschirm auszudrucken, kann die Implode-Funktion von PHP dieses einfache Array schnell in Datenzeilen aufteilen.

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

Sie können die zurückgegebenen Daten auch verwenden, um herauszufinden, wie viele Posts über diese Metawerte verfügen, indem Sie beispielsweise eine einfache Schleife über die zurückgegebenen Daten durchführen und ein Array der Zähler erstellen.

$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.
*/

Diese Logik könnte auf verschiedene Arten von Daten angewendet und auf eine beliebige Anzahl verschiedener Arten erweitert werden. Daher hoffe ich, dass meine Beispiele hilfreich und einfach genug waren, um zu folgen.

t31os
quelle
3
Auch ein Spaß für zukünftige Betrachter, wenn Sie nur eindeutige Metawerte abrufen möchten - geben Sie diese DISTINCTdirekt nach der SELECTin der obigen Funktion ein. Könnte nützlich sein.
Howdy_McGee
Ich denke, das ist äußerst nützlich
Pablo SG Pacheco
Wie man das macht und die Werte sortiert
zurückgibt
14

Ich möchte dem obigen Code von t31os nur eine Kleinigkeit hinzufügen . Ich habe "SELECT" in "SELECT DISTINCT" geändert, um doppelte Einträge zu vermeiden, wenn ich diesen Code selbst verwendet habe.

Lehooo
quelle
1
Ich kann mir Fälle vorstellen, in denen es gültig wäre, mehrere Metawerte mit demselben Wert zu haben, und diesen Zusatz nicht zu meinem Code gemacht habe. Wenn Sie eindeutige Werte wünschen, ist dies jedoch der richtige Weg. Darüber hinaus können Sie dies als Argument für die Funktion hinzufügen (damit Sie sie gegebenenfalls verwenden können oder nicht).
24.
10

Es ist nicht gut oder erforderlich, das globale $ wpdb zu verwenden:

// 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 );
Leon Francis Shelhamer
quelle
Dies wäre in den meisten Fällen meine bevorzugte Methode. Es werden nicht nur eine, sondern fünf Abfragen durchgeführt. Da jedoch die standardmäßigen WordPress-Prozeduren zum Generieren und Übermitteln dieser Abfragen verwendet werden, werden alle plattformspezifischen Caching-Vorgänge (z. B. das Object Caching von WP Engine oder ein zufälliges Plugin) aktiviert werden für die Dauer der Anfrage im internen Cache von WordPress gespeichert und müssen daher bei Bedarf nicht erneut aus der Datenbank abgerufen werden.
Andrew Dinmore
Alle Filter werden auch auf die Daten angewendet, die beispielsweise auf einer mehrsprachigen Site von großer Bedeutung sein können. Da nur die Standardfunktionen von WordPress verwendet werden, ist es weniger wahrscheinlich, dass ein zukünftiges Update zu Problemen führt.
Andrew Dinmore
4

Der schnellste Weg wäre eine benutzerdefinierte SQL-Abfrage und ich bin nicht sicher, aber Sie können es versuchen

$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
");

Wenn überhaupt, dann ist es ein Anfang.

Bainternet
quelle
1
danke, aber sollten kundenspezifische fragen nicht "um jeden preis" vermieden werden? Ich würde es vorziehen, die WP-Abstraktionsebene zu verwenden (heißt sie so?) ... aber natürlich, wenn dies nicht möglich ist.
mikkelbreum
Benutzerdefinierte Abfragen können besser sein, wenn sie richtig geschrieben sind, und Sie sollten sie nur vermeiden, wenn Sie nicht wissen, was Sie tun.
Bainternet
1
Ich stimme mit mwb überein. Benutzerdefinierte Abfragen sind sehr nützlich und praktisch, aber ich denke, sie sind auch viel schwerer in der DB. Insbesondere mit SRT-Funktionen.
krembo99
3

Zum Abrufen aller Metawerte über einen Metaschlüssel

Überprüfen Sie wp-> db wordpress codex

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );
Wiki
quelle
3
Das Problem bei diesem Ansatz ist die mangelnde Spezifität. Bei einer solchen Abfrage werden zahlreiche Ergebnisse erzielt, darunter Entwürfe, verworfene Elemente, Posts, Seiten und alle anderen vorhandenen Post-Typen. Sie sollten niemals nach dem fragen, was Sie nicht benötigen. Hier ist mit Sicherheit eine bestimmte Angabe erforderlich.
24.
Es ist zwar richtig, dass Sie Werte von anderen Beitragstypen und -status abrufen können, aber manchmal benötigen Sie nur die Werte, und Sie haben diesen meta_key nirgendwo verwendet, außer dort, wo Sie ihn benötigen. Wenn alle / die meisten Werte eindeutig sind, ist dies möglicherweise die beste Lösung.
Luke Gedeon
2

Es gibt keinen Grund, warum Sie t31os und Bainternets Code nicht zusammenführen können, um eine wiederverwendbare vorbereitete Anweisung (WordPress-Stil) zu erhalten, die die Anzahl und die Werte in einer effizienten Operation zurückgibt.

Es handelt sich um eine benutzerdefinierte Abfrage, die jedoch weiterhin die Abstraktionsschicht der WordPress-Datenbank verwendet. Es spielt also beispielsweise keine Rolle, wie die Tabellennamen wirklich lauten oder ob sie sich ändern, und es handelt sich um eine vorbereitete Anweisung, damit wir vor SQL-Angriffen usw .

In diesem Fall überprüfe ich nicht mehr den Beitragstyp und schließe leere Zeichenfolgen aus:

    $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;

In diesem besonderen ist

Dies wird ein Array von Objekten wie folgt zurückgeben:

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)
benz001
quelle
0

Verwenden Sie mit foreach Folgendes

 $key = get_post_custom_values( 'key' );

Angenommen, der Name Ihres benutzerdefinierten Feldschlüssels lautet

Dev
quelle
Beachten Sie, dass dies standardmäßig der aktuelle Beitrag ist, wenn keine post_id angegeben ist.
Birgire