投稿の「いいね」のステータスを投稿メタとして保存する機能があります。私はそれを気に入ったユーザーと "like"を関連付けたいので、 "like_status_ {user_id}"({user_id}は現在ログインしているユーザーのID)というカスタムフィールドを0または0として保存します。 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,
));
他の誰かがその投稿を気に入ったときにその投稿を気に入った人全員に通知を送信しようとしています...「他の誰かがあなたが気に入った投稿が好きでした。ぜひチェックしてください」しかし、私は他の誰かがその投稿を気に入っているかどうか、そしてもしそうであれば誰になるかを知るための方法が必要です。
それが不可能な場合は、1人のユーザーのような投稿のステータスをすばやく更新する効率を維持しながら、このデータをpost_metaとして格納するためのより良い方法を提案できますか?
残念ながら、meta_query
を使用しているときは、meta_key
値に対してLIKE
比較を使用してWP_Query
を実行することはできません。私はこの道を下りてきた….
代わりに、カスタムテーブルのユーザーメタやメタではなく、ポストメタとして同様のステータス関係を維持する場合は、他に2つのオプションがあります。
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...
}
});
注:必要に応じてロジックをさらに単純化することができます。
WP_Query
と一緒にmeta_query
を使うことができますオプション2では、メタキーをlike_status_{user_id}
からlike_status
やliked_by_user_id
などの汎用的なものに変更する必要があります。この場合、キーに対して1
の値を格納する代わりに、代わりにユーザーのIDを値として格納します。
//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);
}
});
});
あなたの質問に具体的に答えることは非常に困難です。しかし最初の部分は簡単です。私は最近何かをしました 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 );
カスタムフィールドはパフォーマンスに影響を与えません。この件に関する私の投稿を読むことができます ここ 。しかし、私はあなたが各記事が何百または何千ものいいねを持つことができると言うことによって悩んでいます。これは、このような大量のカスタムフィールドデータを取得してキャッシュするパフォーマンスに影響を与える可能性があります。データベースを大量の不要なカスタムフィールドデータで詰まらせる可能性があるため、保守が非常に困難になります。
シリアル化されたデータで検索や注文をすることはできないため、カスタム化されたフィールドにシリアル化されたデータを格納することはあまり好きではありません。ただし、1つのカスタムフィールドの下にすべてのユーザーIDを配列で格納することをお勧めします。ユーザーが投稿を好む場合は、単にユーザーIDで配列を更新するだけです。カスタムフィールドデータを取得し、IDの配列をループしてIDを使って何かをするのは簡単です。 get_post_meta()
を見てください。
カスタムフィールドを更新することも簡単です。そのためには、 update_post_meta()
を調べる必要があります。カスタムフィールドの作成方法はわかりませんが、update_post_meta()
は間違いなく使用したいものです。
カスタムフィールドが更新されたときに電子メールまたはプッシュ通知を送信する必要がある場合は、次のフックを使用して作業できます。 ( コンテキストについては update_metadata()
を参照 )
この記事を投稿する直前に、シリアル化された経路に進む前に、並べ替えられたデータで並べ替えたり、シリアル化されたデータ内の特定のデータを検索する必要がないことを確認します。
後でもっと詳細な統計、機能などでこれを拡張したい場合は、さらに別の方法があります。 カスタムテーブル
pros :あなたのニーズに合わせたもので、 indexed にするとパフォーマンスが向上します。
短所 :もっと作業
カスタム分類法を使用した回避策もあるかもしれません。コアテーブルがどのようにインデックス付けされているかによって、ポストメタクエリよりもクエリパフォーマンスが向上する可能性があります。
他の誰かがその投稿を気に入ったときにその投稿を気に入った人全員に通知を送信しようとしています...「他の誰かがあなたが気に入った投稿が好きでした。ぜひチェックしてください」しかし、私は他の誰かがその投稿を気に入っているかどうか、そしてもしそうであれば誰になるかを知るための方法が必要です。
あなたがここでどんな通知を意味しているのかわからないが、これはすぐに大きくなる可能性がある。
例 :〜1000の投稿が好きで、各投稿が〜1000のお気に入りがあるユーザー。その場合、パイプ内に1Mの通知があります。これらが電子メール通知である場合、ホストプロバイダは満足していない可能性があり、ユーザーは夢中になります。それはまた第三者の電子メールサービスと高価かもしれません。
WordPress 5.1以降、今では以下のようなメタクエリを使用することが可能です。
WP_Meta_Query のドキュメントによれば、WP_Queryのmeta_query
引数にcompare
引数を使用することができます。ただし、比較できるのはvalue
ではなくkey
なので、これをどのように構成するかを再考することをお勧めします。
like
引数は次のようになります。
$arguments = array(
'meta_query' => array(
array(
'key' => 'foo',
'value' => 'ba',
'compare' => 'LIKE'
)
)
);
$query = new WP_Query($arguments);
key
で 'LIKE'検索を実行できないことを考えれば、ユーザーメタにお気に入りの投稿を追加し、その投稿が気に入ったユーザーを WP_User_Query 検索することをお勧めします。
$arguments = array(
'meta_query' => array(
array(
'key' => 'liked_post',
'value' => '<post_id>'
)
)
);
$users = new WP_User_Query($arguments);