É possível ordenar por várias meta_keys ao usar meta_value_num?

4

Lendo o pedido & orderby documentation , não está claro para mim se existe algum suporte para o pedido com base em vários valores meta_key .

Obviamente, usar meta_query posso retornar postagens com base em vários pares de valores-chave, mas quero controlar a ordem em que esses resultados são retornados com base em vários meta_keys .

Por exemplo, tenho páginas que têm várias categorias e cada categoria tem uma classificação numérica. Se um usuário estiver pesquisando páginas que estão em uma das três categorias diferentes, posso retornar todas as postagens necessárias com o seguinte:

$query = array(
  'order' => 'DESC',
  'orderby' => 'meta_value_num',
  'meta_query' => array(
    'relation' => 'OR',
    array( 'key' => 'cat1', 'type' => 'numeric' ),
    array( 'key' => 'cat2', 'type' => 'numeric' ),
    array( 'key' => 'cat3', 'type' => 'numeric' )
  );
);

No entanto, assim que eles forem retornados, eu gostaria que eles fossem solicitados com base no maior valor numérico em qualquer uma das categorias nas quais os resultados foram retornados. Em outras palavras, as postagens com um valor 9 em cat1 apareceriam na mesma ordem das postagens com um valor 9 em cat3 .

Analisando esta resposta , parece que um meta_key nem sequer é necessário para 'orderby' => 'meta_value_num' , mas que não corresponde à documentação para meta_value , que é muito mais documentada do que meta_value_num ... Qualquer esclarecimento seria útil. Obrigado!

    
por Dan 16.01.2013 / 21:00

2 respostas

1

Você pode querer verificar as melhorias de consulta no WP 4.2 para "orderby" e "meta_query". Detalhes estão em enlace .

Tente nomear suas cláusulas meta_query e faça o pedido delas.

O código a seguir não foi testado:

$query = array(
  'order' => 'DESC',
  'meta_query' => array(
    'relation' => 'OR',
    'cat1-clause' => array( 'key' => 'cat1', 'type' => 'numeric' ),
    'cat2-clause' => array( 'key' => 'cat2', 'type' => 'numeric' ),
    'cat3-clause' => array( 'key' => 'cat3', 'type' => 'numeric' )
  );
  'orderby' => array(
    'cat1-clause' => 'ASC',
    'cat2-clause' => 'ASC',
    'cat3-clause' => 'ASC',
  ),
);
    
por Pim Schaaf 24.06.2016 / 06:46
0

Se você olhar para o método get_posts de WP_Query, é fácil depurar o sql enviando a variável passada para o filtro posts_request .

// Debug the WP_Query sql
add_filter( 'posts_request', function( $sql ) {
  echo "<pre>";
  var_dump( $sql );
  echo "</pre>";
  return $sql;
} );

O resultado deve ser algo como isto:

string(426) "SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND (
  wp_postmeta.meta_key = 'cat1'
  OR
  wp_postmeta.meta_key = 'cat2'
  OR
  wp_postmeta.meta_key = 'cat3'
) GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value+0 DESC LIMIT 0, 10"

A consulta pode parecer correta no início, mas não é. Ele usa o meta_value da primeira linha na junção interna para a cláusula ORDER BY . Nesse caso, isso é 'cat1' . Para alterar esse comportamento, podemos usar o gancho posts_orderby para alterar a instrução ORDER BY e usar a função MAX mysql para que use o valor mais alto de todos os meta_values em vez de apenas a primeira linha.

// Filter to alter the orderby sql
function nvdGMCWh_alter_posts_orderby( $sql ) {
  return "MAX( $wpdb->postmeta.meta_value+0 ) DESC";
} // - alter_posts_orderby
// Register the filter
add_filter( 'posts_orderby', 'nvdGMCWh_alter_posts_orderby' );

// The WP_Query
$res = new WP_Query;
$args = [
  'order' => 'DESC',
  'orderby' => 'meta_value_num',
  'meta_query' => [
    'relation' => 'OR',
    ['key' => 'cat1', 'type' => 'numeric'],
    ['key' => 'cat2', 'type' => 'numeric'],
    ['key' => 'cat3', 'type' => 'numeric'],
  ],
]; // - $args
// Execute the query and get the results
$result = $res->query( $args );
// Clean up the filter so it won't affect later queries
remove_filter( 'posts_orderby', 'nvdGMCWh_alter_posts_orderby' );
// Loop through the results
foreach ( $result as $post ) {
  // ... code here
} // - foreach
    
por forsvunnet 19.04.2015 / 13:49