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.


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!


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


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
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.