메타 키를 기준으로 목록을 먼저 정렬하고 (존재하는 경우) 메타 키없이 나머지 게시물을 제목순으로 표시하도록 쿼리


22

게시 날짜 (사용자 정의 날짜 필드)로 정렬 된 용어에 연결된 항목을 원하고 같은 날에 여러 항목이있는 경우 (YYYY-MM- DD)를 클릭하여 제목별로 정렬하고 맞춤 입력란이 작성되지 않은 경우 제목별로 정렬합니다 (이전 항목).

따라서 WP_query를 사용하여 수백 가지 방법으로 시도한 결과 원하는 결과를 대부분 반환하지만이 경우 publishing_date의 meta_key가있는 항목 만 반환합니다. 다른 모든 항목은 무시되고 표시되지 않습니다. "또는"의 관계를 사용하여 meta_query를 시도하고 publish_date를 EXISTS 및 NOT EXISTS로 비교했지만 결과는 0입니다.

또한이 사이트는 여전히 3.5.2를 실행하고 있으며 업그레이드를 원하지 않습니다.

다음은 publishing_date 사용자 정의 필드가 올바른 순서로 표시되는 게시물을 가져 오는 가장 최근의 쿼리입니다.

$term = get_queried_object(); // find the term of the taxonomy page we are on
$wp_query = new WP_Query( array(
'post_type' => 'resource',
'tax_query' => array(
    array(
        'taxonomy' => 'resource_types',
        'field' => 'slug',
        'terms' => $term->name,
    )), 

'meta_key' => 'publication_date',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'paged' => $paged,
'posts_per_page' => '10',
));

또한 wpdb를 사용하고 SQL 쿼리를 실행하려고 시도했지만 실제로 원하는 작업을 수행하는 방법을 잘 모르겠습니다. 누군가 나를 도울 수 있다면 정말 좋을 것입니다!

미리 감사드립니다.


meta_query 접근 방식이 작동하지 않았다는 사실에 놀랐지 만 meta_key를 설정하지 않고 meta_query를 사용하여 메타 값을 정렬 할 수 없습니다.
sanchothefat

나는 그것이 내가 겪고있는 문제라고 생각합니다. 마지막으로 메타 쿼리가 작동 'meta_query' => array( 'relation' => 'OR', array( //check to see if date has been filled out 'key' => 'publication_date', 'compare' => '!=', 'value' => date('Y-m-d'), ), array( //if no date has been added show these posts too 'key' => 'publication_date', 'value' => date('Y-m-d'), 'compare' => 'NOT EXISTS' ) ),했지만 주문이 작동하지 않습니다 : \
CSSgirl

예, 순서는 meta_key가 불행하게도 tax_query 외부에서 설정되는 것에 의존합니다. 아래 답변이 도움이 될 수 있습니다.
sanchothefat

답변:


19

도와 주셔서 감사합니다!

결국 아래 쿼리는 내가 원하는 결과를 얻었습니다. 먼저 "publication_date"의 사용자 정의 필드로 게시물을 표시하고 정렬했습니다.-날짜별로 정렬하고 동일한 날짜가 여러 개인 경우 (예 : 4로 표시) 2013 년 6 월) 제목별로 정렬합니다. 그런 다음 게시 날짜가 채워진 모든 게시물을 통과 한 후 제목별로 알파벳순으로 나머지 게시물을 반복합니다.

이것은 나에게 같은 쿼리에서 결과 세트를 얻고 내 페이지 매김을 유지합니다.

$term = get_queried_object();
the_post();
$wp_query = new WP_Query( array(
'post_type' => 'resource',
    'tax_query' => array(
        array(
            'taxonomy' => 'resource_types',
            'field' => 'slug',
            'terms' => $term->name,
        )),
 'meta_query' => array(
       'relation' => 'OR',
        array( //check to see if date has been filled out
                'key' => 'publication_date',
                'compare' => '=',
                'value' => date('Y-m-d')
            ),
          array( //if no date has been added show these posts too
                'key' => 'publication_date',
                'value' => date('Y-m-d'),
                'compare' => 'NOT EXISTS'
            )
        ),
'meta_key' => 'publication_date',
'orderby' => 'meta_value title',
'order' => 'ASC',
'paged' => $paged,
'posts_per_page' => '10',
));

1
좋은. 나는 meta_query같은 키 에서 두 개를 실행하려고 생각하지 않았습니다 !
GhostToast

5
나를 위해 (WordPress 4.1.1 사용), meta_key자동으로 설정 하면로도 포함되지 않습니다 NOT EXISTS. 정말 내가 잘못하고 있기를 바랍니다.
Ryan Taylor

1
@RyanTaylor 여기에서 동일-메타 키는 쿼리에서 작동하도록 설정되어서는 안되지만 메타 키가 설정되지 않은 경우에도 메타 값으로 올바르게 정렬되는 것처럼 보입니다.
jammypeach

2
위의 주석처럼 WP 4.1+의 경우 제거하거나 주석 처리하십시오 'meta_key' => 'publication_date',.
MikeiLL

7

몇 년 후, CSSGirl이 게시 한 코드는 메타 키가 없거나 메타 키가 비어있는 게시물이 있었기 때문에 작동하지 않았습니다. 따라서 모든 게시물을 날짜순으로 정렬해야합니다. 메타 키 값이 표시된 것을 먼저 표시하십시오.

$args          = array(
'post_type'   => $type,
'post_status' => 'publish',
'nopaging'    => TRUE,
'meta_query'  => array(
    'relation' => 'OR',
    array(
        'key'     => $meta_key,
        'compare' => 'NOT EXISTS',
    ),
    array(
        'relation' => 'OR',
        array(
            'key'   => $meta_key,
            'value' => 'on',
        ),
        array(
            'key'     => $meta_key,
            'value'   => 'on',
            'compare' => '!=',
        ),
    ),
),
'orderby'     => array( 'meta_value' => 'DESC', 'date' => 'DESC' ),
);

1

두 개의 별도 루프를 수행해야한다고 생각합니다. 첫 번째 루프에서 찾은 모든 게시물을 캡처하여 보조 루프에서 쉽게 제외시킬 수 있습니다.

$found_posts = array();
while($loop->have_posts()): $loop->the_post();
    // loop stuff
    $found_posts[] = get_the_id();
endwhile;

wp_reset_query();

$args = array(
    // other args
    'post__not_in' => $found_posts,
);

그런 다음 두 번째 루프를 실행하십시오.


지금 시도해 주셔서 감사합니다. 작동하는지 알려드립니다!
CSSgirl

1
이것은 효과가 있었지만 페이지 매김을 깨뜨 렸습니다. 어떻게 작동시키는 지 아십니까? 현재 모습은 다음과 같습니다.echo paginate_links( array( 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 'format' => '?page=%#%', 'current' => max( 1, get_query_var('paged') ), 'total' => $publication_query->max_num_pages, 'prev_text' => __('Previous |'), 'next_text' => __('| Next'), ) );
CSSgirl

흠. 내가 생각할 수있는 것은 아닙니다.
GhostToast

1

빈 값으로 모든 게시물에 publish_date 메타 키를 적용 할 수없는 이유가 있습니까?

따라서 save_post작업에서 $_POST값이 비어 있는지 여부에 관계없이 메타 키를 추가 / 업데이트합니다 .

이전 게시물을 반복하고 빈 값으로 키를 추가하려면 업데이트 스크립트를 실행해야합니다. 예 :

add_action( 'admin_init', 'update_old_posts' );
function update_old_posts() {
    if ( ! isset( $_GET[ 'update_old_posts' ] ) )
         return;

    foreach( get_posts() as $post ) {
        if ( false === get_post_meta( $post->ID, 'publication_date', true ) ) {
             update_post_meta( $post->ID, 'publication_date', '' );
             echo "Updated {$post->post_title} <br />";
        }
    }

    die;
}

http://example.com/wp-admin/?update_old_posts 를 찾아서 실행하십시오 .

그런 다음 가지고있는 것과 동일한 쿼리를 사용할 수 있습니다. 다른 방향으로 다른 열을 기준으로 정렬 할 수 있도록 추가 필터를 추가하고 싶을 때 날짜별로 내림차순으로 정렬하고 제목을 오름차순으로 정렬하는 것이 좋습니다.

add_filter( 'posts_orderby', 'multicolumn_orderby', 10, 2 );
function multicolumn_orderby( $orderby, $query ) {
    global $wpdb;

    // check it's the right query
    if ( $query->get( 'meta_key' ) == 'publication_date' ) {
         $orderby = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_title ASC";
    }

    return $orderby;
}

흠, 나는 그것을 생각하지 않았다. 나는 그것을 시도하고 그것이 어떻게되는지, 감사합니다!
CSSgirl

0

사용자 정의 where 절을 작성했습니다. $wp_query->request내 메인 루프 바로 앞에서 사용하여 테스트했지만 실제로 SQL을 잘 모르지만 작동하는 것처럼 보입니다.

add_action('pre_get_posts', 'add_trending_sort', 11, 1);
function add_trending_sort($query){
  if(!$query->is_main_query())
    return;

  //Overwrite query arguments
  $query->set('meta_query', array(
    array(
      'key' => 'TRENDING',
      //'value' => 'asdfasdf',//may need a value for older versions of WordPress
      'compare' => 'NOT EXISTS',
    )
  ));
  $query->set('orderby', 'meta_value_num date');
  $query->set('order', 'DESC');
}

add_filter('posts_where', 'add_trending_where');
function add_trending_where($where = ''){
  global $wpdb, $wp_query;
  if(!$wp_query->is_main_query())//Not sure if this really works.  Should be OK
    return $where;

  $where .= " OR ( $wpdb->postmeta.meta_key = 'TRENDING' )";

  // Don't run this twice
  remove_filter('posts_where', 'add_trending_where');

  return $where;
}

다른 방법으로는 설정할 수 compare'EXISTS'및에 add_trending_where에 줄을 변경 $where .= " OR ($wpdb->postmeta.post_id IS NULL)";. 그런 다음 한 곳에서 키의 값만 변경하면됩니다. 다시 한 번 $wp_query->request더 잘 이해하거나 조정하려면 에코 하고 재생하십시오.

편집 : 방금 meta_key쿼리에 설정되어 있으면 작동하지 않는 것으로 나타났습니다 . $query->set('meta_key', NULL);필요한 경우 사용할 수 있습니다 .

편집 2 : 위의 방법 으로이 작업을 수행했습니다. 어떤 이유로 든 처음에는 없었습니다 (아마 meta_key가 설정되었을 수도 있습니다 ... 모름).

add_action('pre_get_posts', 'add_trending_sort', 11, 1);
function add_trending_sort($query){
  // Bail if not the main "hidden" query, as opposed to a 'new WP_Query()' call
  if(!$query->is_main_query())
    return;

  // Set meta_query to get shares for orderby, and also get non-shared content.
  $query->set('meta_query', array(
    'relation' => 'OR',
    array(
      'key' => 'TRENDING',
      'compare' => 'NOT EXISTS',
    ),
    array(
      'key' => 'TRENDING',
      'compare' => 'EXISTS',
    )
  ));
  //$query->set('meta_key', NULL);
  $query->set('orderby', array('meta_value_num' => 'DESC', 'date' => 'DESC'));
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.