부분 메타 키로 게시물을 어떻게 쿼리합니까?


9

게시물의 "유사"상태를 게시물 메타로 저장하는 기능이 있습니다. "like"를 좋아하는 사용자와 연관 시키려고하므로 0으로 저장하는 "like_status_ {user_id}"(여기서 {user_id}는 현재 로그인 한 사용자의 ID 임)라는 사용자 정의 필드를 설정했습니다. 1. 여러 개의 "좋아요"가있는 게시물의 경우 db에 다음과 같이 설정되는 몇 가지 메타 값이 있습니다.

'meta_key' = 'like_status_0'
'meta_value' = 1
'meta_key' = 'like_status_2'
'meta_value' = 1
'meta_key' = 'like_status_34'
'meta_value' = 1

....등등.

특정 게시물에 수천 개의 좋아요가있을 수 있습니다. 다른 사람이 해당 게시물을 좋아했는지 보여주는 쿼리를 어떻게 실행합니까?

나는 이런 식으로 생각하고 있었다 :

$query = new WP_Query(array(
    'meta_key' => 'like_status_{user_id}',
    'meta_value' => 1,
));

다른 사람이 해당 게시물을 좋아할 때 게시물을 좋아 한 모든 사람에게 알림을 보내려고합니다. "다른 사람이 좋아하는 게시물을 좋아했습니다. 확인해야합니다!" 그러나 다른 사람이 해당 게시물을 좋아했는지 여부를 알 수있는 방법이 필요합니다.

가능하지 않은 경우 게시물에서 단일 사용자와 같은 상태를 빠르게 업데이트하는 효율성을 유지하면서이 데이터를 post_meta로 저장하는 더 좋은 방법을 제안 할 수 있습니까?

답변:


6

불행히도를 사용할 때 값을 비교 meta_query하여 사용할 수 없습니다 . 나는이 길을 따라 갔다 ...LIKEmeta_keyWP_Query

대신 사용자 정의 테이블의 사용자 메타 및 메타가 아닌 포스트 메타와 같은 상태 관계를 유지하려는 경우 몇 가지 다른 옵션이 있습니다.

옵션 1

  • 메타 스키마를 수정할 필요가 없습니다
  • 사용하는 wpdb사용자 지정 쿼리를 수행하는 클래스를

예:

//when a user likes a post...
$current_user_id = get_current_user_id();
add_post_meta($current_user_id, "like_status_{$current_user_id}", 1, false);

//later in the request...
global $wpdb;

$results = $wpdb->get_results(
    "
    SELECT meta_key 
    FROM {$wpdb->prefix}postmeta 
    WHERE meta_key 
    LIKE 'like_status_%'
    ",
    ARRAY_N
);

$results = array_map(function($value){

    return (int) str_replace('like_status_', '', $value[0]);

}, $results);

array_walk($results, function($notify_user_id, $key){

    //apply to all users except the user who just liked the post
    if ( $notify_user_id !== $current_user_id ) {
        //notify logic here...           
    }

});

참고 : 원하는 경우 논리를 더 단순화 할 수 있습니다.

옵션 2

  • 메타 스키마를 변경해야합니다.
  • 사용자 ID를 메타 값으로 저장해야합니다.
  • WP_Query함께 사용할 수 있습니다meta_query

옵션 2에서는 메타 키를 키 like_status_{user_id}와 비교하여 값을 저장하는 대신 범용 키로 변경 like_status하거나 사용자의 ID를 값으로 저장해야합니다.liked_by_user_id1

//when a user likes a post...
$current_user_id = get_current_user_id();
add_post_meta($current_user_id, "liked_by_user_id", $current_user_id, false);

//later in the request
$args = array(
    'post_type'  => 'post', //or a post type of your choosing
    'posts_per_page' => -1,
    'meta_query' => array(
        array(
            'key' => 'liked_by_user_id',
            'value' => 0,
            'type' => 'numeric'
            'compare' => '>'
        )
    )
);

$query = new WP_Query($args);   

array_walk($query->posts, function($post, $key){

    $user_ids = get_post_meta($post->ID, 'liked_by_user_id');

    array_walk($user_ids, function($notify_user_id, $key){

        //notify all users except the user who just like the post
        if ( $notify_user_id !== $current_user_id ) {

            //notify logic here...
            //get user e.g. $user = get_user_by('id', $notify_user_id);

        }

    });

});

1
5.1 내 대답은 아래에서 살펴 갖고 있기 때문에 그것은 지금
K. 트롬 프

@ K.Tromp Huzzah!
Adam

최신 WP 기능 또는 @ K.Tromp의 답변이 최신 답변으로 표시되도록 허용 된 답변을 업데이트하십시오.
zumek

10

귀하의 질문에 구체적으로 답변하는 것은 매우 어렵습니다. 첫 번째 부분은 쉽습니다. 최근 에 stackoverflow에서 비슷한 작업을 수행했습니다.

메타 키가 비교되고 정확하게 일치합니다. WP_Query간단한 매개 변수를 사용하여이 동작을 조정할 수있는 방법은 없지만 항상 자신을 소개 한 다음 posts_where절을 조정하여 LIKE메타 키를 비교할 수 있습니다.

필터

이것은 기본 필터 일 뿐이며 필요에 따라 조정하십시오.

add_filter( 'posts_where', function ( $where, \WP_Query $q )
{ 
    // Check for our custom query var
    if ( true !== $q->get( 'wildcard_on_key' ) )
        return $where;

    // Lets filter the clause
    $where = str_replace( 'meta_key =', 'meta_key LIKE', $where );

    return $where;
}, 10, 2 );

보다시피, 새 맞춤 매개 변수를 wildcard_on_key로 설정하면 필터가 실행됩니다 true. 이 체크 아웃, 우리는 간단하게 변경하면 =받는 비교기 LIKE비교기

이것에 대한 메모, LIKE비교는 본질적으로 다른 비교를 실행하는 데 더 비쌉니다.

쿼리

메타 키가있는 모든 게시물을 가져 오려면 다음과 같이 게시물을 간단히 쿼리 할 수 ​​있습니다. like_status_{user_id}

$args = [
    'wildcard_on_key' => true,
    'meta_query'      => [
        [
            'key'   => 'like_status_',
            'value' => 1,
        ]
    ]
];
$query = new WP_Query( $args );

다른 질문

맞춤 입력란은 성능에 영향을 미치지 않습니다 . 이 주제에 대한 내 게시물을 여기 에서 읽을 수 있습니다 . 그러나 각 게시물이 수백 또는 수천 개의 좋아요를 가질 수 있다고 말하면서 문제가 발생합니다. 이렇게하면 대량의 사용자 정의 필드 데이터를 가져오고 캐싱 할 수 있습니다. 또한 막대한 양의 불필요한 사용자 정의 필드 데이터로 DB를 방해하여 유지 관리가 매우 어렵습니다.

직렬화 된 데이터로 검색하거나 주문할 수 없으므로 사용자 정의 필드에 직렬화 된 데이터를 저장하는 데 열심이 아닙니다. 그러나 모든 사용자 ID를 하나의 사용자 정의 필드 아래 배열로 저장하는 것이 좋습니다. 사용자가 게시물을 좋아할 때 사용자 ID로 배열을 업데이트하기 만하면됩니다. 사용자 정의 필드 데이터를 가져오고 ID 배열을 반복하고 ID로 무언가를 수행하는 것은 쉽습니다. 그냥 봐get_post_meta()

사용자 정의 필드를 업데이트하는 것도 쉽습니다. 이를 위해, 당신은 update_post_meta()당신의 사용자 정의 필드를 만드는 방법을 모르지만 update_post_meta()확실히 사용하고 싶은 것입니다.

사용자 정의 필드가 업데이트 될 때 이메일 또는 푸시 알림을 보내야하는 경우 다음 후크를 사용할 수 있습니다. ( 컨텍스트 참조update_metadata() )

결론

이 게시물을 게시하기 직전에 다시 직렬화 된 경로로 이동하기 전에 정렬 된 데이터를 기준으로 정렬하거나 직렬화 된 데이터 내에서 특정 데이터를 검색 할 필요가 없는지 확인하십시오.


1
post_meta 성능에 대한 설명에 감사드립니다! 매우 유용합니다.
codescribblr

이것은 허용되는 답변이어야합니다. 사용자 정의 쿼리를 사용하는 것보다 항상 필터를 사용하는 것이 좋습니다. 또한 WP_Query 대신 get_posts를 사용하는 경우 suppress_filters => false를 통과해야합니다. 그렇지 않으면 필터가 트리거되지 않습니다. 메타 키에서 LIKE를 수행하려면 원하는 유사 검색 유형에 따라 배열의 키 앞뒤에 %를 입력해야합니다.
Earle Davies

그리고 게시물을 쿼리하고 싶지만 접두사로 게시물 메타 키가있는 모든 게시물을 제외하려면 어떻게 필터링합니까? (예 : 게시물 메타 LIKE 'my_prefix_'??
gordie

6

wordpress 5.1부터는 다음과 같은 메타 쿼리를 사용할 수 있습니다. 여기에 이미지 설명을 입력하십시오


밑줄을 피하는 것이이 방법에 문제가있는 것처럼 보이지만 그렇지 않으면 꽤 좋습니다. 감사합니다.
Jake

2

나중에에이 등 더 자세한 통계 기능으로,이를 확장 할 경우, 또 다른 대안이 될 수 있습니다 : 사용자 정의 테이블 (들)

  • 장점 : 필요에 맞게 조정하고 더 나은 성능을 위해 색인생성 할 수 있습니다 .

  • 단점 : 더 많은 작업

코어 테이블의 색인 방식에 따라 메타 쿼리 게시보다 쿼리 성능이 향상 될 수있는 사용자 지정 분류법을 사용하는 해결 방법이있을 수도 있습니다.

다른 사람이 해당 게시물을 좋아할 때 게시물을 좋아 한 모든 사람에게 알림을 보내려고합니다. "다른 사람이 좋아하는 게시물을 좋아했습니다. 확인해야합니다!" 그러나 다른 사람이 해당 게시물을 좋아했는지 여부를 알 수있는 방법이 필요합니다. 그렇다면 누구에게 연락해야하는지 알 수 있습니다.

여기에서 어떤 종류의 알림을 의미하는지 잘 모르는 경우 신속하게 커질 수 있습니다.

: ~ 1000 개의 게시물을 좋아하고 각 게시물 ~ ~ 1000 개의 좋아하는 사용자는 파이프에 1M 개의 알림이 있으며 해당 사용자에 대해서만! 이메일 알림 인 경우 호스트 제공 업체가 만족스럽지 않고 사용자가 미쳐 버릴 수 있습니다. 타사 전자 메일 서비스를 사용하면 비용이 많이들 수 있습니다.


실제로 게시물 당 한 사람당 한 번만 알림을 보냅니다. 소리는 작지만 여전히 많이 들지만 내장 테이블을 사용하려고하는 이유는이 데이터로 실제 앱에서 표준 WP REST API를 사용할 수 있기를 원하기 때문입니다.
codescribblr

-1

WP_Meta_Query의 문서에는 사용할 수 compare에 인수 meta_queryWP_Query의 인수를. 그러나, 당신은 단지에 비교할 수 value와하지 key당신이 할 수 있도록이를 구성하는 방법을 다시 생각합니다.

like인수는 다음과 같이 보일 것이다 :

$arguments = array(
    'meta_query' => array(
        array(
            'key' => 'foo',
            'value' => 'ba',
            'compare' => 'LIKE'
        )
    )
);

$query = new WP_Query($arguments);

' key좋아요 '검색을 수행 할 수없는 경우 사용자 메타에 좋아하는 게시물을 추가하고 해당 게시물을 좋아하는 사용자에 대해 WP_User_Query 검색을 수행하는 것이 좋습니다 .

$arguments = array(
    'meta_query' => array(
        array(
            'key' => 'liked_post',
            'value' => '<post_id>'
        )
    )
);

$users = new WP_User_Query($arguments);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.