it-swarm.com.de

Kann wp_query Beiträge in einer einzelnen Anfrage als Meta zurückgeben?

Ich möchte eine wp_query erstellen, die Posts-Meta innerhalb des Arrays posts zurückgibt.

$args = array (
    'post_type' => 'page',
    'meta_key' => 'someMetaKeyName',
);

// The Query
$query = new WP_Query( $args );

Das ergibt so etwas wie:

enter image description here

Wie Sie sehen, haben die Posts keine Metadaten. Ist es möglich, die Metadaten auch in das zurückgegebene Array aufzunehmen?

PS Ich möchte aus Performancegründen keine zusätzlichen wp_queries.

20
YemSalat

Standardmäßig gibt WP_Query die Standardobjekte WP_Post für die abgefragten Posts zurück. Ich glaube, mit einigen cleveren Änderungen und der Verwendung der in WP_Query angegebenen Filter können Sie dem zurückgegebenen WP_Post objects-Array Objekte hinzufügen.

Wird das performant sein? Meiner Meinung nach beeinträchtigt dies die Leistung, da Sie die Ergebnisse in Ihrer Abfrage zusammenführen müssen, da benutzerdefinierte Felder nicht in der Tabelle wp_posts, sondern in der Tabelle wp_postmeta gespeichert werden

Das Abrufen von Post-Meta ist sehr schnell und erfordert keine zusätzliche Instanz von WP_Query. Sie können das benutzerdefinierte Feld einfach mit get_post_meta() aufrufen. WordPress war sehr nachdenklich, als die benutzerdefinierten Felder eingeführt wurden. Sie haben einen Cache hinzugefügt, um sie zwischenzuspeichern. Unabhängig davon, ob Sie 1 oder 100 benutzerdefinierte Felder abfragen, treffen Sie die Datenbank einmal, superschnell. Für einen vollständigen Test und eine Erklärung siehe diesen Beitrag den ich kürzlich zu diesem Thema gemacht habe.

Meiner Meinung nach lohnt sich der zusätzliche Datenbankaufruf und die tatsächlich aufgewendete Zeit und sind schneller als das Umschreiben von WP_Query, sodass benutzerdefinierte Felder in das von $posts zurückgegebene Standardpostobjekt einbezogen werden.

20
Pieter Goosen

Vor kurzem hatte ich ein ähnliches Problem. Ich musste 7 Metadaten eines benutzerdefinierten Beitragstyps abrufen, aber ich musste den Beitrag auch auf der Grundlage von Metadaten abrufen.

Deshalb habe ich die folgende SQL-Anweisung erstellt, die ich häufig verwende. Hoffentlich hilft es jemand anderem. Ich werde versuchen, es so gut wie möglich zu erklären.

        global $wpdb;
        $pt = 'clients';
        $mk = 'trainerid';
        $mv = $pid;
        $mk1 = 'email';
        $mk2 = 'phone';
        $mk3 = 'gender';
        $mk4 = 'dob';
        $mk5 = 'photo';
        $mk6 = 'registrationts';
        $mk7 = 'activationts';
        $ord = 'p.post_name ASC';

        $sql = "
        SELECT p.ID, p.post_title AS fullname, pm1.meta_value AS email, pm2.meta_value AS phone, pm3.meta_value AS gender, pm4.meta_value AS dob, pm5.meta_value AS photo, pm6.meta_value AS regts, pm7.meta_value AS actemailts
        FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID
            AND pm.meta_key = '{$mk}'
            LEFT JOIN {$wpdb->postmeta} pm1 ON pm1.post_id = p.ID
            AND pm1.meta_key = '{$mk1}'
            LEFT JOIN {$wpdb->postmeta} pm2 ON pm2.post_id = p.ID
            AND pm2.meta_key = '{$mk2}'
            LEFT JOIN {$wpdb->postmeta} pm3 ON pm3.post_id = p.ID
            AND pm3.meta_key = '{$mk3}'
            LEFT JOIN {$wpdb->postmeta} pm4 ON pm4.post_id = p.ID
            AND pm4.meta_key = '{$mk4}'
            LEFT JOIN {$wpdb->postmeta} pm5 ON pm5.post_id = p.ID
            AND pm5.meta_key = '{$mk5}'
            LEFT JOIN {$wpdb->postmeta} pm6 ON pm6.post_id = p.ID
            AND pm6.meta_key = '{$mk6}'
            LEFT JOIN {$wpdb->postmeta} pm7 ON pm7.post_id = p.ID
            AND pm7.meta_key = '{$mk7}'
            WHERE pm.meta_value = '{$mv}'
            AND p.post_type = '{$pt}'
            AND p.post_status NOT IN ('draft','auto-draft')
            ORDER BY {$ord}
        ";

        $clients = $wpdb->get_results( $wpdb->prepare( $sql ), OBJECT );

Zuerst bekomme ich die WordPress-Datenbankfunktionen mit globalem $ wpdb. Dann setze ich den Posttyp mit $ pt. Um den korrekten Beitrag zu erhalten, der einem bestimmten Wert in post_meta entspricht, setze ich $ mk (meta_key)

Dann setze ich die Variable $ mv (meta_value). (In diesem Fall stimmt der Meta-Wert mit einer Post-ID überein.)

$ mk1- $ mk7 sind die Metaschlüssel, die ich von jedem Beitrag haben möchte. (Ich werde die Werte in der Select-Anweisung greifen)

Ich mache auch die 'order by' ein var, indem ich $ ord setze

Die select-Anweisung lautet wie folgt: Ich wähle die Beitrags-ID und den Beitragstitel aus dem POST oder 'p.'

Dann wähle ich alle Metadaten aus, die ich mit pm1 auswählen muss. -> pm.7 und nimm den meta_value und benenne ihn um (AS), damit er besser lesbar ist, wenn du die Daten von meinem Objekt abrufst.

Ich erstelle einen LEFT JOIN für die Metadaten, die ich für den Beitrag benötige. (pm)

Ich erstelle 7 linke Joins für jede der Metadaten, die ich abrufen muss. (pm1-pm7)

Die WHERE-Anweisung basiert auf dem ersten LEFT JOIN (pm), sodass ich nur die Posts benötige, bei denen die Metadaten übereinstimmen.

Ich füge auch ein "UND" für den Beitragstyp und für die post_statuses hinzu, die keine Entwürfe sind. (also nur veröffentlichte Beiträge)

Schließlich füge ich die 'order by'-Klausel hinzu.

Dies funktioniert schnell und mit den in Wordpress integrierten Indizes. Es scheint also effizient zu sein.

Ich weiß nicht, ob etwas besser ist als dieses, aber wenn ja, würde ich es gerne verwenden.

Hoffe das hilft.

Marcus

4
Marcus

Diese Frage ist mehr als 1 Jahr alt, aber ich habe das gleiche Problem, und hier ist eine Funktion, die jeden meta_value und meta_key zum $ wp_query-Objekt hinzufügt.

anstatt jede Post-Meta-In-While-Schleife abzufragen, führt diese Funktion ein zusätzliches Abfragebeispiel aus:

"SELECT meta_key, meta_value, post_id FROM $ wpdb-> postmeta WHERE post_id IN (1,2,3,4,5 ...)"

dabei ist (1,2,3,4,5 ...) die aktuelle Post-ID von $ wp_query

if(!function_exists('add_query_meta')) {
  function add_query_meta($wp_query = "") {

      //return In case if wp_query is empty or postmeta already exist
      if( (empty($wp_query)) || (!empty($wp_query) && !empty($wp_query->posts) && isset($wp_query->posts[0]->postmeta)) ) { return $wp_query; }

      $sql = $postmeta = '';
      $post_ids = array();
      $post_ids = wp_list_pluck( $wp_query->posts, 'ID' );
      if(!empty($post_ids)) {
        global $wpdb;
        $post_ids = implode(',', $post_ids);
        $sql = "SELECT meta_key, meta_value, post_id FROM $wpdb->postmeta WHERE post_id IN ($post_ids)";
        $postmeta = $wpdb->get_results($sql, OBJECT);
        if(!empty($postmeta)) {
          foreach($wp_query->posts as $pKey => $pVal) {
            $wp_query->posts[$pKey]->postmeta = new StdClass();
            foreach($postmeta as $mKey => $mVal) {
              if($postmeta[$mKey]->post_id == $wp_query->posts[$pKey]->ID) {
                $newmeta[$mKey] = new stdClass();
                $newmeta[$mKey]->meta_key = $postmeta[$mKey]->meta_key;
                $newmeta[$mKey]->meta_value = maybe_unserialize($postmeta[$mKey]->meta_value);
                $wp_query->posts[$pKey]->postmeta = (object) array_merge((array) $wp_query->posts[$pKey]->postmeta, (array) $newmeta);
                unset($newmeta);
              }
            }
          }
        }
        unset($post_ids); unset($sql); unset($postmeta);
      }
      return $wp_query;
  }
}

Zusätzliche "Postmeta" werden in jeden $ wp_query-> Post geschrieben [$ i]

$wp_query->posts[0]->postmeta

Beispiel mit 'someMetaKeyName' vergessen Sie nicht zu setzen

add_query_meta() zu deinem Theme functin.php

$args = array (
    'post_type' => 'page',
    'meta_key' => 'someMetaKeyName',
);

// The Query
$query = new WP_Query( $args );
if($wp_query->have_posts()) {
  $wp_query = add_query_meta($wp_query);
    $i = 0;
    while($wp_query->have_posts()) {
      $wp_query->the_post();
      $post_id = get_the_id();

      //Get $someMetaKeyName in current post
      foreach($wp_query->posts[$i]->postmeta as $k => $v) {
        switch($v->meta_key) {
          case('someMetaKeyName') : {
            $someMetaKeyName = $v->meta_value;
            break;
          }
        }
      }

      //Your Code here
      //Example 
      echo isset($someMetaKeyName) ? '<h3>'.$someMetaKeyName.'</h3>' : '';


      $i++;
    }
}
3
Jonny

Hey, bitte versuchen Sie es mit diesem, ich denke, es funktioniert gut.

$args = array(
            'post_type' => 'page',
            'meta_key' => 'someMetaKeyName',
            'meta_query' => array(
                array(
                        'key' => 'someMetaKeyName',
                        'type' => 'CHAR',
                   ),
                ),
        );

    $query = new WP_Query( $args );
0
Amit Mishra