¿Puede wp_query devolver meta en una sola solicitud?

17

Me gustaría crear una wp_query que devolvería las metadatos dentro de la matriz posts .

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

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

Esto devuelve algo como:

Como puede ver, las publicaciones no tienen metadatos, ¿es posible incluir los metadatos también en la matriz devuelta?

PS No quiero wp_queries adicionales por razones de rendimiento.

    
pregunta YemSalat 12.12.2014 - 04:09

4 respuestas

17

De forma predeterminada, WP_Query devuelve el estándar WP_Post objetos para las publicaciones que se consultan. Creo que con una reescritura inteligente y el uso de los filtros dados en WP_Query puede agregar objetos a la matriz de objetos devueltos WP_Post .

Será esto un ejecutante. En mi opinión, afectaré más el rendimiento, ya que tendrá que unir los resultados en su consulta, ya que los campos personalizados no se guardan en la tabla wp_posts , sino en la tabla wp_postmeta

La recuperación del metadatos es realmente rápida y no requiere ninguna instancia adicional de WP_Query . Simplemente puede llamar al campo personalizado con get_post_meta() . Wordpress tiene mucha consideración cuando se introdujeron los campos personalizados. Agregaron un caché para almacenarlos en caché, por lo que si está consultando 1 o 100 campos personalizados, está presionando la db una vez, superrápida. Para una prueba completa y una explicación, consulte esta publicación que he hecho recientemente sobre este tema

En mi opinión, la llamada adicional a la base de datos y el gasto en tiempo real vale la pena y es más rápido que reescribir WP_Query de tal manera que incluya campos personalizados en el objeto de publicación estándar devuelto por $posts

    
respondido por el Pieter Goosen 12.12.2014 - 05:37
4

Recientemente tuve un problema similar, necesitaba obtener 7 piezas de metadatos de un tipo de publicación personalizada, pero también necesitaba obtener la publicación basada en una pieza de metadatos.

Así que creé la siguiente declaración SQL, la uso a menudo. Esperemos que ayude a alguien más. Intentaré explicarlo lo mejor que pueda.

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

Primero obtengo las funciones de la base de datos de wordpress con $ wpdb global. Luego establezco el posttype con $ pt. Para obtener la publicación correcta que coincida con un valor específico en post_meta, establezco $ mk (meta_key)

Luego establezco la variable $ mv (meta_value). (en este caso, el valor meta coincide con un postid)

$ mk1- $ mk7 son las meta_keys que quiero de cada publicación. (Agarraré los valores en la declaración de selección)

También hago el 'order by' a var, estableciendo $ ord

La declaración de selección es la siguiente: Selecciono la ID de la publicación y el post_título de la POST o 'p.'

Luego selecciono todos los metadatos que necesito seleccionándolos con pm1. - > pm.7 y capturar el meta_valor y cambiar su nombre (AS) para que sea más legible al recuperar los datos de mi objeto.

Creo un IZQUIERDA ÚNICA para los metadatos que necesito para hacer coincidir con la publicación. (pm)

Creo 7 uniones a la izquierda para cada uno de los metadatos que necesito recuperar. (pm1-pm7)

La instrucción WHERE se basa en el primer IZQUIERDA IZQUIERDA (pm) para que sepa que solo necesito las publicaciones donde coincidan los metadatos.

También agrego un 'AND' para el tipo de publicación, y para los post_statuses que no son borradores. (solo publicaciones publicadas)

Finalmente agrego la cláusula "ordenar por".

Esto funciona rápido y con los índices incorporados en Wordpress, por lo que parece eficiente.

No sé si algo es mejor que esto, pero si lo es, me encantaría usarlo.

Espero que esto ayude.

Marcus

    
respondido por el Marcus 14.02.2017 - 02:21
3

Esta pregunta tiene más de 1 año, pero tengo el mismo problema, y aquí está la función que agregará cada meta_valor y meta_key al objeto $ wp_query,

En lugar de consultar cada meta meta de entrada, esta función hará una consulta adicional ejemplo:

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

donde (1,2,3,4,5 ...) se consultan actualmente los ID de los mensajes desde $ 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;
  }
}

Additioanal "postmeta" se escribirá en cada $ wp_query- > posts [$ i]

$wp_query->posts[0]->postmeta

Ejemplo con 'someMetaKeyName' no olvides poner

add_query_meta() a tu functin.php de tema

$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++;
    }
}
    
respondido por el Jonny 05.05.2016 - 15:10
0

Oye, prueba este, creo que funciona bien.

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

    $query = new WP_Query( $args );
    
respondido por el Amit Mishra 12.12.2014 - 04:44

Lea otras preguntas en las etiquetas