如何按部分元键查询帖子?

时间:2016-03-26 作者:codescribblr

我有一个函数,将帖子的“like”状态存储为post meta。我想将这个“like”与喜欢它的用户相关联,所以我设置了一个名为“like\\u status\\uuu{user\\u id}”(其中{user\\u id}是当前登录用户的id)的自定义字段,并将其存储为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,
));
当其他人喜欢某个帖子时,我试图向所有喜欢该帖子的人发送通知。。。比如,“嘿,有人喜欢你喜欢的帖子。你应该去看看!”但我需要一种方法来找出是否有人喜欢这个帖子,如果是,他们会是谁,这样我才能通知他们。

如果不可能,您能否建议一种更好的方法,将这些数据存储为post\\u meta,同时保持快速更新帖子上单个用户的相似状态的效率?

5 个回复
最合适的回答,由SO网友:Adam 整理而成

很遗憾,您无法执行meta_query 使用LIKE 比较meta_key 使用时的值WP_Query. 我一直在走这条路。。。

相反,如果您想在自定义表中维护与post meta类似的状态关系,而不是用户meta和/或meta,那么您还有几个其他选项。

选项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要求您更改元架构,因为元值允许您使用WP_Query 随着meta_querylike_status_{user_id} 对于一些通用的东西,例如like_statusliked_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);
            
        }

    });

});

SO网友:Pieter Goosen

很难具体回答你的问题。第一部分很简单。我最近做了点什么similar on 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_keytrue. 当这个检查出来时,我们只需更改= 比较器到LIKE 比较器

只需要注意一下,LIKE 进行其他比较固有的成本更高

查询

您只需按如下方式查询您的帖子,即可获得所有带有元键的帖子like_status_{user_id}

$args = [
    \'wildcard_on_key\' => true,
    \'meta_query\'      => [
        [
            \'key\'   => \'like_status_\',
            \'value\' => 1,
        ]
    ]
];
$query = new WP_Query( $args );
其他问题自定义字段对性能没有影响,您可以阅读我关于此主题的帖子here. 然而,你说每个帖子都有成百上千的赞,这让我很困扰。这可能会影响获取和缓存如此大量自定义字段数据的性能。它还可以用大量不必要的自定义字段数据阻塞数据库,这使得维护变得非常困难。

我不太喜欢在自定义字段中存储序列化数据,因为人们无法按序列化数据进行搜索或排序。但是,我建议将所有用户ID存储在一个自定义字段下的数组中。当用户喜欢帖子时,只需使用用户ID更新数组即可。获取自定义字段数据、在ID数组上循环以及使用ID执行操作都很容易。看看吧get_post_meta()

更新自定义字段也很容易。为此,您需要调查update_post_meta(), 我不知道如何创建自定义字段,但是update_post_meta() 绝对是你想要使用的东西。

如果需要在更新自定义字段时发送电子邮件或推送通知,可以使用以下挂钩。(参见update_metadata() 用于上下文

SO网友:K. Tromp

由于wordpress 5.1,现在可以使用元查询,如:enter image description here

SO网友:birgire

如果以后您想通过更详细的统计数据、功能等来扩展此功能,那么另一种选择可能是:custom table(s)

专业人士:根据您的需要量身定制,并可编制索引,以获得更好的性能。

缺点:更多工作

由于核心表的索引方式,还可能有一种使用自定义分类法的变通方法,可以提供比post元查询更好的查询性能。

当其他人喜欢某个帖子时,我试图向所有喜欢该帖子的人发送通知。。。比如,“嘿,有人喜欢你喜欢的帖子。你应该去看看!”但我需要一种方法来找出是否有人喜欢这个帖子,如果是,他们会是谁,这样我才能通知他们。

不确定您在这里指的是什么类型的通知,但这可能会很快变得笨重。

Example: 一个喜欢1000条帖子的用户,每个帖子都会得到1000条,那么管道中就有100万条通知,只针对该用户!如果这些是电子邮件通知,那么主机提供商可能会不高兴,用户会发疯。使用第三方电子邮件服务也可能会很贵。

SO网友:LonnyLot

根据WP_Meta_Query 文档您可以使用compare 中的参数meta_query WP\\u查询的参数。但是,您只能在value 而不是key 所以你可能想重新思考一下你是如何构建这个的。

A.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);

相关推荐

如何在wp-Query中比较不同的时间戳以获取事件自定义帖子类型?

我有一个带有自定义元数据库的自定义帖子类型(as seen on wptheming.com) 并且希望进行查询以显示即将发生的事件,例如在侧边栏中,过去的日期被忽略。但我需要一个当前时间的值来和事件开始时间进行比较。现在我从current_time(\'mysql\') 看起来是这样的:2012-02-16 13:15:31元的开始时间如下所示:201108121100如何使这两个日期具有可比性?我可以在查询中执行吗?或者是否有其他解决方案?以下是我到目前为止的查询(值留空,时间戳回显):<?ph