meta_query ordenando por 2 chaves

8

Preciso classificar postagens (personalizadas) por 2 valores de campos personalizados ...

nome do campo personalizado 1: is_sponsored[o valor pode ser 1ou 0]

nome do campo personalizado 2: sfp_date[ timestamptambém conhecido como data atual da postagem em segundos]

As postagens cujo is_sponsoredvalor " " é 1 precisam estar no topo, classificadas por " sfp_date" na DESCordem final. Todas as outras postagens cujo is_sponsoredvalor " " é 0 devem ser listadas abaixo - em ordem decrescente (por " sfp_date") também.

Eu tenho algo como:

$sfp_query_args = array(
    'tax_query'   => array( 
        array( 
            'taxonomy' => 'sfp_posts',
            'terms'    => array( 1, 5, 8 )
        )
    ),
    'post_type'   => 'sfpposts',
    'post_status' => 'publish',
    'showposts'   => 15,
    'paged'       => $paged,
    'meta_key'    => 'sfp_date', 
    'orderby'     => 'meta_value_num', 
    'order'       => 'DESC', 
    'meta_query'  => array(
        'key'          => 'is_sponsored',
        'value'        => 2,
        'type'         => 'NUMERIC',
        'compare'      => '<='
    )
);
$wp_q = new WP_Query( $sfp_query_args );

... mas não está funcionando. Alguma ideia?


Nota do Editor: Este é um pequeno plug-in que deve mostrar a aparência da consulta, pois provavelmente não temos nenhum conjunto de dados disponível para testar isso.

<?php
/** Plugin Name: (#67600) Dump Query parts */
function wpse67600_dump_query_parts( $pieces )
{
    echo '<pre>'.var_export( $pieces, true ).'</pre>';
    return $pieces;
}
add_filter( 'posts_clauses', 'wpse67600_dump_query_parts' );

OP ADICIONE SAÍDA DO PLUGIN AQUI - use o link "editar" .

EDIT by Dameer

OK, depois de rastrear a solicitação e várias soluções alternativas, criei o seguinte ...

Se eu simplificar "$ sfp_query_args" um pouco, o resultado está próximo do necessário, no entanto, a incapacidade de classificar as postagens permanece como está. Aqui está:

$sfp_query_args1 = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => (int)$per_page,
    'paged' => $paged,
    'meta_key' => 'is_sponsored', 
    'orderby' => 'meta_value date'
);
  • * orderby usa dois atributos: meta_value e date *

Portanto, $ wpdb-> request com os argumentos acima na consulta fica assim:

SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID 
FROM $wpdb->posts 
INNER JOIN $wpdb->term_relationships 
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) 
INNER JOIN $wpdb->postmeta 
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) 
WHERE 1=1 
AND $wpdb->posts.post_type = 'sfpposts' 
AND ($wpdb->posts.post_status = 'publish') 
AND ($wpdb->postmeta.meta_key = 'is_sponsored' ) 
GROUP BY $wpdb->posts.ID 
ORDER BY $wpdb->postmeta.meta_value, $wpdb->posts.post_date DESC 
LIMIT 0, $per_page

E, finalmente, para poder classificar também por meta_value, a consulta deve ser definida com apenas uma pequena diferença:

SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID 
FROM $wpdb->posts 
INNER JOIN $wpdb->term_relationships 
ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) 
INNER JOIN $wpdb->postmeta 
ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) 
WHERE 1=1 
AND $wpdb->posts.post_type = 'sfpposts' 
AND ($wpdb->posts.post_status = 'publish') 
AND ($wpdb->postmeta.meta_key = 'is_sponsored' ) 
GROUP BY $wpdb->posts.ID 
ORDER BY $wpdb->postmeta.meta_value [!ORDER MISSING!], $wpdb->posts.post_date DESC 
LIMIT 0, $per_page

Localize o espaço reservado [! ORDER MISSING!]. Eu acho que o acima exposto deve explicar onde exatamente o problema ocorre.

Dameer
fonte
Não acredito que você possa fazer isso com a classe WP_Query padrão. Mesmo nos documentos, ele diz "Você sabe como classificar a consulta se o meta_value for uma matriz? Escreva aqui". Você provavelmente terá que escrever sua própria consulta SQL para isso.
Miha Rekar
Pois é, eu sei que ainda não foi resolvido, mas eu pensei que este é o lugar certo para resolver o problema :)
Dameer
Adicionei um pequeno plug-in à sua pergunta, para que você possa nos mostrar as partes finais da consulta SQL. Edite sua pergunta com essas informações. Obrigado.
Kaiser #
Ah, e aqui estão algumas informações de uma pergunta relacionada sobre como a classificação funciona em geral.
Kaiser #

Respostas:

2

OK, a solução final seria dividir a consulta:

$sfp_query_args = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_post_category', 'terms' => $cat_id_arr ) ),
    'meta_key' => 'is_sponsored',
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => (int)$per_page,
    'paged' => $paged
);

... e use o filtro "posts_orderby" para modificar a parte ORDER:

add_filter( 'posts_orderby', 'sfp_modify_orderby' );
function sfp_modify_orderby( $orderby ) {
    if( !is_admin() && is_tax( 'sfp_post_category' ) ) {
        global $wpdb;
        $orderby = " $wpdb->postmeta.meta_value DESC, $wpdb->posts.post_date DESC ";
    }
    return $orderby;
}

Provavelmente, você precisará remover o filtro após o loop na página para evitar que 'posts_orderby' afete qualquer outra consulta (barra lateral ou rodapé). Então, aqui está outra função para colocar em "functions.php":

function sfp_remove_orderby_filter() {
    remove_filter( 'posts_orderby', 'sfp_modify_orderby' );
}

... e na página usando nosso filtro de descarte de consulta:

if( have_posts() ) : while( have_posts() ) : the_post();
    // code
endwhile;
else :
    // code
endif;

sfp_remove_orderby_filter();

Espero que faça sentido!

Dameer
fonte
-1

Estou escrevendo sua consulta modificando um pouco. Espero que ajude.

$sfp_query_args = array(
    'tax_query' => array( array( 'taxonomy' => 'sfp_posts', 'terms' => array( 1, 5, 8) ) ),
    'post_type' => 'sfpposts',
    'post_status' => 'publish',
    'showposts' => 15,
    'paged' => $paged, 
    'meta_key'=>'sfp_date', 
    'meta_query' => array(
    array(
        'key' => 'sfp_date',
            'type' => 'NUMERIC',
    ),
    array(
        'key' => 'is_sponsored',
        'value' => '2',
        'compare' => '<='
    )       
    ),
    'orderby' => 'meta_value_num', 
    'order' => 'DESC',
);
$wp_q = new WP_Query( $sfp_query_args );

Por favor, deixe-me saber se funciona ou não :-)

Md Toufiqul Islam
fonte
2
Isso ordenaria por padrão (por data), já que você não fornece 'meta_key'.
Miha Rekar
Obrigado @MihaRekar, foi um erro, obrigado pela sua correção
Md Toufiqul Islam
Receio que não funcione, apenas classifica as postagens por data sem colocar aqueles que possuem o valor "is_sponsored" de 1 no topo.
9609 Dameer
Estou procurando encontrar uma solução para isso. Pode ser que @MihaRekar esteja certo. Você pode ter que escrever consulta personalizada sql para este
Md Toufiqul Islam
Existe uma maneira de fornecer um exemplo de consulta mySQL "normal"?
9609 Dameer