O wp_query pode retornar as postagens meta em uma única solicitação?


22

Eu gostaria de criar um wp_query que retornaria posts meta dentro da postsmatriz.

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

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

Isso retorna algo como:

insira a descrição da imagem aqui

Como você pode ver, as postagens não possuem metadados, é possível incluir também os metadados na matriz retornada?

PS: Não quero wp_queries adicionais por motivos de desempenho.


2
O WP_Query padrão não retorna os metadados das postagens. As únicas opções que você tem são: 1) executar get_post_metaem chaves individuais, 2) executar get_post_custompara obter todos os campos personalizados de uma postagem de uma só vez ou 3) criar sua própria consulta usando a classe $ wpdb ( get_results()) para criar seu próprio objeto de retorno . (documentação da classe $ wpdb: codex.wordpress.org/Class_Reference/wpdb )
— BODA82

Respostas:


20

Por padrão, WP_Queryretorna os WP_Postobjetos padrão para as postagens que estão sendo consultadas. Acredito que, com alguma reescrita inteligente e o uso dos filtros fornecidos, WP_Queryvocê pode adicionar objetos à WP_Postmatriz de objetos retornados .

Será este um desempenho? Na minha opinião, isso prejudicará mais o desempenho, pois você precisará associar os resultados na sua consulta, pois os campos personalizados não são salvos na wp_poststabela, mas na wp_postmetatabela

A recuperação da meta meta é realmente rápida e não requer nenhuma instância extra de WP_Query. Você pode simplesmente chamar o campo personalizado com get_post_meta(). O WordPress foi muito atencioso quando os campos personalizados foram introduzidos. Eles adicionaram um cache para armazená-los, portanto, se você estiver consultando 1 ou 100 campos personalizados, estará atingindo o banco de dados uma vez, super rápido. Para um teste e explicação completos, consulte este post que fiz recentemente sobre esse assunto.

Na minha opinião, a chamada extra ao banco de dados e o tempo real gasto valem a pena e são mais rápidos do que reescrever de WP_Queryforma a incluir campos personalizados no objeto de postagem padrão retornado por$posts


OK, obrigado, eu escolherei este como aceito, mas, para ser honesto, é tão complicado chamar get_post_meta()todas as postagens. Prefiro que haja uma maneira de armazenar dados adicionais diretamente na wp_poststabela ou em um tabela relacionada que não é tão preocupante quanto wp_postsmetaé.
— YemSalat

Bem, para ser sincero, seja para chamá get_post_meta()-lo como um objeto de postagem, você precisará chamá-lo em todas as postagens. É o mesmo com as tags de modelo como the_content(), você deve chamá-lo em todas as postagens.
— Pieter Goosen

2
Isso significa que, se você tiver que mostrar 120 postagens, terá 120 consultas extras em sua página?
— Chifliiiii

Todos os postdata são salvos em um cache, assim você não terá consultas extras quando cal; ling meta pós
— Pieter Goosen

Você está certo. Eu estava me referindo a post_thumbnails, mas recentemente encontrei update_post_thumbnail_cache ($ the_query). Obrigado de qualquer maneira para o esclarecimento
— chifliiiii

4

Esta pergunta tem mais de um ano, mas eu tenho o mesmo problema, e aqui está a função que adicionará cada meta_value e meta_key ao objeto $ wp_query,

em vez de consultar cada meta postada no loop while, esta função fará um exemplo extra de consulta:

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

em que (1,2,3,4,5 ...) são IDs de postagem consultadas com cuidado de $ 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" será gravado em cada $ wp_query-> posts [$ i]

$wp_query->posts[0]->postmeta

Exemplo com 'someMetaKeyName' não se esqueça de colocar

add_query_meta() ao seu tema 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++;
    }
}

Eu amo essa solução.
— Armstrongest

3

Recentemente, tive um problema semelhante, precisava obter 7 partes de metadados de um tipo de postagem personalizado, mas também precisava obter a postagem com base em uma parte de metadados.

Então, eu criei a seguinte instrução SQL, eu a uso frequentemente. Espero que ajude alguém. Vou tentar explicar da melhor maneira possível.

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

Primeiro, recebo as funções do banco de dados wordpress com o global $ wpdb. Depois, defino o posttype com $ pt. Para obter a postagem correta que corresponda a um valor específico em post_meta, defino o $ mk (meta_key)

Então eu defino a var $ mv (meta_value). (nesse caso, o valor meta corresponde a um postid)

$ mk1- $ mk7 são as meta_keys que eu quero de cada post. (Vou pegar os valores na instrução select)

Também faço o 'order by' a var, definindo $ ord

A instrução select é a seguinte: seleciono o ID da postagem e o post_title no POST ou 'p'.

Depois, seleciono todos os metadados necessários para selecioná-los com pm1. -> pm.7 e pegando o meta_value e renomeando-os (AS) para ficar mais legível ao recuperar os dados do meu objeto.

Eu crio um JOIN ESQUERDO para os metadados que preciso corresponder à postagem. (PM)

Eu crio 7 junções esquerdas para cada um dos metadados que preciso recuperar. (pm1-pm7)

A instrução WHERE é baseada no primeiro LEFT JOIN (pm), para que saiba que eu preciso apenas das postagens onde os metadados correspondem.

Também adiciono um 'AND' para o tipo de postagem e para os post_statuses que não são rascunhos. (apenas postagens publicadas)

Finalmente, adiciono a cláusula 'order by'.

Isso funciona rápido e com os índices internos do Wordpress, por isso parece eficiente.

Não sei se algo é melhor que isso, mas se for, eu adoraria usá-lo.

Espero que isto ajude.

Marcus


Obrigado, este post é muito útil. Eu criei uma visão com todos os campos de meta que eu preciso e agora é fácil muito rápido e para obter todos os dados que eu quero
— Liko

0

Ei, por favor, tente este aqui, acho que funciona bem.

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

    $query = new WP_Query( $args );

Por que você usou meta_keye meta_query[]['key']também?
— Kaiser

1
Não, isso não funciona e traz de volta a matriz de postagens sem meta associada a elas.
— YemSalat

3
meta_keye / ou meta_querynão modifique o tipo de resultado retornado, apenas a própria consulta.
— BOX82
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.