programing

WordPress: meta_query가 있는 게시물 제외 - 모든 게시물에 meta_field가 있는 것은 아닙니다.

codeshow 2023. 10. 29. 20:01
반응형

WordPress: meta_query가 있는 게시물 제외 - 모든 게시물에 meta_field가 있는 것은 아닙니다.

사용자 지정 메타 필드의 값이 지정된 모든 게시물을 제외하고 싶습니다.문제는 모든 게시물에 이 메타 필드가 있는 것은 아니라는 것입니다.

내 코드는 다음과 같습니다(워킹 루프 제외).

// WP_Query arguments
        $args = array (
            'post_parent'   => $parentid,
            'orderby'       => 'menu_order',
            'order'         => 'ASC',
            'post_type'     => array( 'page' ),
            'meta_query' => array(
                array(
                    'key' => 'hide',
                    'value' => 1,
                    'compare' => '!='
                )
            )
        );

모든 게시물이 "숨김" 필드를 사용하는 것은 아닙니다.NULL을 돌려주는 게시물도 있는데 그래서 루프가 안 되는 것 같아요?!

이거 맞는건가요?모든 게시물에 해당 키에 대한 값이 있어야 하나요?

또 다른 방법:

// WP_Query arguments
    $args = array (
    'post_parent'   => $parentid,
    'orderby'       => 'menu_order',
    'order'         => 'ASC',
    'post_type'     => array( 'page' ),
    'meta_query' => array('0' => array('key' => 'hide', 'value' => '1', 'compare' => 'NOT EXISTS')
    )
);

이것은 오래된 게시물이지만 어쨌든 대답하기 위해서 입니다.이 질문의 메타 쿼리는 해당 메타 키를 가진 게시물의 결과만 반환합니다.해당 메타키가 전혀 없는 게시물도 반환하려면 추가 메타 쿼리가 필요합니다.예:

// WP_Query arguments
$args = array (
    'post_parent'   => $parentid,
    'orderby'       => 'menu_order',
    'order'         => 'ASC',
    'post_type'     => array( 'page' ),
    'meta_query'    => array(
        'relation'  => 'OR',
        array(
            'key'       => 'hide',
            'value'     => 1,
            'compare'   => '!='
        ),
        array(
            'key'       => 'hide',
            'compare'   => 'NOT EXISTS'
        )
    )
);

"relation"과 'NOT EXISTRESS'의 비교값을 갖는 두 번째 메타 쿼리의 사용에 유의하십시오.

현재 이 상황을 어떻게 처리할지 업데이트:

이런 상황이 점점 더 많이 발생하는 것 같고, 이를 처리하는 방법을 개발하여 훨씬 더 빠른 SQL 쿼리를 수행하게 되었습니다.해당 게시물 유형의 게시물이 저장될 때마다 조회 기준에 맞는 게시물 ID 목록을 업데이트하여 WP 옵션에 저장합니다.그런 다음 쿼리가 실행되면 이 목록이 표시되고 화이트리스트인지 블랙리스트인지에 따라 '포함' 또는 '제외' 쿼리 매개 변수에 이 목록을 넣습니다.

이렇게 하면 코드가 조금 더 추가되지만 성능 면에서 이점이 있으며, 실행해야 하는 다른 메타 쿼리가 있는 경우에는 복잡성을 제거할 수 있습니다.블랙리스트에 대한 아래의 몇 가지 예시 코드는 화이트리스트에도 적용될 수 있습니다.

class Example_Meta_Blacklist
{

    public function init()
    {
        /*
         * Trigger whenever post is saved, you could also trigger on save_post_{$post->post_type}
         * If you are using Advanced Custom Fields, you may need to use acf/save_post
         */
        add_action( 'save_post', [ $this, 'update_my_custom_post_type_blacklist' ] );

        /*
         *  One time use function to create an initial list if needed. Remove if not.
         */
        add_action( 'wp', [ $this, 'create_initial_my_custom_post_type_blacklist' ] );
    }

    /*
     *  Add or remove post ids from our list whenever the post is saved
     */
    public function update_my_custom_post_type_blacklist( $post_id )
    {
        if ( 'my_custom_post_type' != get_post_type( $post_id ) ) {
            return;
        }

        $my_custom_post_type_blacklist  = get_option( 'my_custom_post_type_blacklist', [] );
        $key                            = array_search( $post_id, $my_custom_post_type_blacklist );
        $meta_key_in_question           = get_post_meta( $post_id, 'meta_key_in_question', true );

        if ( ! $meta_key_in_question && $key !== false ) {
            unset( $my_custom_post_type_blacklist[ $key ] );
        } else if ( $meta_key_in_question && $key === false ) {
            $my_custom_post_type_blacklist[] = $post_id;
        }

        update_option( 'my_custom_post_type_blacklist', $my_custom_post_type_blacklist, true );
    }

    /*
     *  When I run into this issue, there are usually already some existing
     *  posts, so I need to run this code one-time to create my initial list
     *  This code would be run by visiting your site with ?gocode=myuniquegocode
     *  at the end of the URL. The function and action hook can then be removed.
     */
    public function create_initial_my_custom_post_type_blacklist()
    {
        if ( ! isset( $_GET['gocode'] ) || 'myuniquegocode' != $_GET['gocode'] ) {
            return;
        }

        $clients = get_posts([
            'posts_per_page'    => -1,
            'post_type'         => 'my_custom_post_type',
            'post_status'       => 'publish',
            'fields'            => 'ids',
            'meta_key'          => 'the_meta_key_in_question',
            'meta_value'        => 'the_meta_value_in_question',
            'meta_compare'      => '='
        ]);

        update_option( 'my_custom_post_type_blacklist', $clients, true );
    }

}

add_action( 'plugins_loaded', [ new Example_Meta_Blacklist, 'init' ] );

그런 다음 게시물에 대한 쿼리에서:

$my_query = new WP_Query( [
    'post_type'     => 'my_custom_post_type',
    'post_status'   => 'publish',
    'exclude'       => get_option( 'my_custom_post_type_blacklist', [] )
] );

아래 스니펫과 같이 하여 SQL 문을 확인해 보십시오.

$customPosts = new WP_Query($yourArgs);
echo "Last SQL-Query: {$customPosts->request}";

언급URL : https://stackoverflow.com/questions/34662455/wordpress-exclude-posts-with-meta-query-not-every-posts-has-the-meta-field

반응형