META_QUERY检查保存值数组的键中的元值

时间:2019-08-11 作者:Arg Geo

在我的自定义帖子类型的每个帖子中调用"announcements" 我将用户ID保存在一个数组中,该数组位于一个名为"post_is_read" 每当用户阅读公告时。

只是解释一下:“post\\u is\\u read”包含一个数组(1、2、5、12、86、100),其中每个数字表示一个用户ID。

我使用以下代码实现了这一点:https://wordpress.stackexchange.com/a/344315/15801

我现在正在尝试创建一个模板,该模板将显示用户未阅读的帖子,代码如下:

$current_user = wp_get_current_user();
$up_an_query_args = array(
    \'post_type\'      => \'announcement\',
    \'post_status\'    => \'publish\',
    \'posts_per_page\' => -1,
    \'orderby\'        => \'date\', 
    \'order\'          => \'DSC\',
    \'meta_query\' => array(
        array(
            \'key\'     => \'post_is_read\', 
            \'value\'   => $current_user->ID,
            \'compare\' => \'NOT IN\',  
        )
    ),                                      
);
我已经阅读了wordpress stackexchange上和下找到的所有相关文章/答案,但没有任何方法对我有效。我能让它工作的最多就是使用\'compare\' => \'NOT LIKE\' 但它把用户ID中至少有一个公共数字(例如1、10、11…等)的帖子显示搞砸了,我理解这是为什么。

2 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

修改后的答案(PS:其实我很久以前就想修改这个答案,但最终还是忘了修改。)

因此,在这个修改后的答案中,主要的一点是下面的第一点,但我希望其余的也能帮助您:

  1. 您试图做的事情不可能(轻松地)以ID的存储方式实现,它是序列化的,例如a:3:{i:0;i:1;i:1;i:10;i:2;i:11;} (用于array( 1, 10, 11 )).

    如果当前用户ID为10,并且在元值中i:10;i:9, i、 e.键入10的数组项的值(用户ID)为9(即。$some_variable[10] = 9), 但是ID 10实际上不在列表中?

    由于上述原因,您最好创建一个自定义数据库表,并将用户ID和帖子ID存储在它们自己的列中。

    如果需要,可以检查简化的example/demo on DB Fiddle.

    或者您可以将每个用户ID存储在名为post_is_read. 这样,过滤帖子就很容易了——但帖子元表最终会非常庞大,有很多很多行。。。

    // Saving the meta:
    add_post_meta( 1, \'post_is_read\', 10 );
    add_post_meta( 1, \'post_is_read\', 11 );
    
    // Then when filtering the posts:
    $user_id = 10;
    $args = array(
        \'meta_key\'     => \'post_is_read\',
        \'meta_value\'   => $user_id,
        \'meta_compare\' => \'!=\',
    );
    $query = new WP_Query( $args );
    
  2. 或者您可以使用序列化值,但存储用户名称/登录名,而不是ID:

    // Store usernames and not IDs.
    $usernames = array( \'foo\', \'user-bar\', \'etc_etc\' );
    
    update_post_meta( 123, \'post_is_read\', $usernames );
    
    然后您可以使用NOT LIKE 类似这样的比较:

    $username = \'user-bar\';
    $args = array(
        \'meta_key\'     => \'post_is_read\',
        \'meta_value\'   => \'"\' . $username . \'"\', // search for exactly "<username>" (including the quotes)
        \'meta_compare\' => \'NOT LIKE\',
    );
    $query = new WP_Query( $args );
    

原始答案

请检查revisions, 但基本上在我最初的回答中,我是说如果你想使用用户ID,那么你可以将它们存储为逗号分隔的列表,如1,10,11 然后使用NOT REGEXP 比较:

// Saving the meta:
update_post_meta( 1, \'post_is_read\', \'1,10,11\' );

// Then when filtering the posts:
$user_id = 10;
$args = array(
    \'meta_key\'     => \'post_is_read\',
    \'meta_value\'   => "(^|,)$user_id(,|$)",
    \'meta_compare\' => \'NOT REGEXP\',
);
$query = new WP_Query( $args );
这确实(现在仍然)有效(WordPress 5.6.1),但在检索元数据时需要额外的解析,例如:

$ids = get_post_meta( 1, \'post_is_read\', true );
$ids = wp_parse_id_list( $ids ); // convert to array

SO网友:Nick C

我将ID存储为字符串,所以这就是我要做的

$up_an_query_args = array(
\'post_type\'      => \'announcement\',
\'post_status\'    => \'publish\',
\'posts_per_page\' => -1,
\'orderby\'        => \'date\', 
\'order\'          => \'DSC\',
\'meta_query\' => array(
    array(
        \'key\'     => \'post_is_read\', 
        \'value\'   => serialize(strval($current_user->ID)),
        \'compare\' => \'LIKE\',  
    )
),);
即使将其存储为int,也应该可以这样做:

\'value\'   => serialize($current_user->ID)

相关推荐

Meta-value query

有点长篇大论,但试图解释清楚:)我正在钻研我的新主题的代码,不熟悉这种类型的数据存储/拉取-有人能帮我理解这里发生了什么吗,请:我试图创建一个页面,只输出附有“优惠券”的帖子优惠券\'存储为帖子的meta\\u密钥。它是meta_value 存储为如下数组(使用打印输出):a: 7:{s:9:“突出显示”;s:14:“测试突出显示”;s:5:“标题”;s:12:“食品五折”;s:11:“描述”;s:16:“测试描述”;s:4:“代码”;s:7:“1524521”;s:11:“弹出图像”;s:4:“4548