워드프레스 기본 검색 범위 확장 – 카테고리와 포스트 메타
By |2020-09-18T16:19:53+09:00September 18th, 2020|개발노트, 워드프레스|0 Comments

기본 검색의 한계와 확장

워드프레스 기본 검색은 범위가 제목, 내용 정도에 한정되어 있다.카테고리와 커스텀 필드를 데이터로 추가하고 싶다면 기능을 추가해주어야 한다.
그리고 하는 김에 띄워쓰기 검색 키워드를 나뉘어 각각 검색도 가능하게 해보자.


사용중인 테마의 functions.php 에 아래와 같은 코드를 추가한다

function expend_default_search( $search, &$wp_query ) {
    global $wpdb;


    if (empty($search)) {
        return $search;
    }
    $search_terms = $wp_query->query_vars[ 's' ];
    $exploded = explode( ' ', $search_terms );
    if( $exploded === FALSE || count( $exploded ) == 0 ) {
        $exploded = array(0 => $search_terms);
    }
    $search = '';
    foreach( $exploded as $tag ) {
        $search .= " AND (
            (wp_posts.post_title LIKE '%$tag%')
            OR (wp_posts.post_content LIKE '%$tag%')
            OR EXISTS (
                SELECT * FROM wp_terms
                INNER JOIN wp_term_taxonomy
                    ON wp_term_taxonomy.term_id = wp_terms.term_id
                INNER JOIN wp_term_relationships
                    ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
                WHERE taxonomy = 'category-name'
                    AND object_id = wp_posts.ID
                    AND wp_terms.name LIKE '%$tag%'
                )
             OR EXISTS (
                SELECT * FROM  wp_postmeta
                WHERE wp_postmeta.post_id = wp_posts.ID
                    AND wp_postmeta.meta_key = 'user-address'
                    AND wp_postmeta.meta_value LIKE '%$tag%'  
                )                 
            )";
    }
    return $search;
}

하나씩 설명을 해보자.

검색 키워드 추출

검색 키워드를 추출한다.

if (empty($search)) {
        return $search;
    }
    $search_terms = $wp_query->query_vars[ 's' ];

우선 검색 키워드가 비어 있는지 확인하여 비어있다면 바로 return 시켜서 함수를 종료한다.
키워드가 들어 있다면 query_vars 를 사용해서 키워드인 s 파라미터를 $search_terms에 저장한다.

키워드 분리 및 저장

$exploded = explode( ' ', $search_terms );
    if( $exploded === FALSE || count( $exploded ) == 0 ) {
        $exploded = array(0 => $search_terms);
    }

키워드가 두 개 이상인 경우 띄워쓰기로 구분하여 키워드를 분리하여 별도로 저장한다.

키워드별로 쿼리 생성

explode 함수를 써서 검색 키워드를 띄워쓰기로 구분하여 따로 저장해준다.
키워드별로 쿼리 생성foreach 문으로 키워드별로 반복하면서 쿼리문을 생성하여 저장한다.여기가 핵심이니 쿼리문을 잘 확인해야 한다.

foreach( $exploded as $tag ) {
        $search .= " AND (
            (wp_posts.post_title LIKE '%$tag%')
            OR (wp_posts.post_content LIKE '%$tag%')
            OR EXISTS (
                SELECT * FROM wp_terms
                INNER JOIN wp_term_taxonomy
                    ON wp_term_taxonomy.term_id = wp_terms.term_id
                INNER JOIN wp_term_relationships
                    ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
                WHERE taxonomy = 'category-name'
                    AND object_id = wp_posts.ID
                    AND wp_terms.name LIKE '%$tag%'
                )
             OR EXISTS (
                SELECT * FROM  wp_postmeta
                WHERE wp_postmeta.post_id = wp_posts.ID
                    AND wp_postmeta.meta_key = 'user-address'
                    AND wp_postmeta.meta_value LIKE '%$tag%'  
                )                 
            )";
    }


보면 쿼리문을 $search 에 .= 을 사용해서 기존 내용에 연속해서 저장한다. 
처음 쿼리 두 줄은 제목과 내용에서 검색하는 내용이다

            (wp_posts.post_title LIKE '%$tag%')
            OR (wp_posts.post_content LIKE '%$tag%')

그리고 카테고리에서 검색하는 쿼리문

OR EXISTS (
                SELECT * FROM wp_terms
                INNER JOIN wp_term_taxonomy
                    ON wp_term_taxonomy.term_id = wp_terms.term_id
                INNER JOIN wp_term_relationships
                    ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
                WHERE taxonomy = 'category-name'
                    AND object_id = wp_posts.ID
                    AND wp_terms.name LIKE '%$tag%'
                )

검색결과에 나온 post에 해당하는 것을 찾아야 하므로 반드시 post의 ID 값이 매칭될 수 있도록 쿼리문이 작성되어야 한다.

그렇기 때문에 wp_terms 에 INNER JOIN 을 사용해서 wp_term_taxonomy 와 wp_term_relationships 까지 거쳐 매칭해준다.

WHERE 구문에서 해당하는지 3가지 조건으로 확인된다.category-name 은 실제로 사용자가 검색할 특정 카테고리를 넣어주면 된다.

모든 taxonomy 에 해당하는 경우 불필요하니 삭제해도 된다.
그리고 post_meta 에서 커스텀 필드의 내용을 검색한다

OR EXISTS (
                SELECT * FROM  wp_postmeta
                WHERE wp_postmeta.post_id = wp_posts.ID
                    AND wp_postmeta.meta_key = 'user-address'
                    AND wp_postmeta.meta_value LIKE '%$tag%'  
                )  


post_meta 에서 user-address 의 값(meta_value)이 검색 키워드와 매치하는 것을 찾는 쿼리문이다.
이렇게 작성된 함수를 추가한 뒤에 add_filter 를 써서 적용시켜주면 된다.

add_filter( 'posts_search', 'expend_default_search', 500, 2 );

위의 코드는 아래 블로그의 글을 보고 참고했습니다.

댓글 남기기