这是我的查询的args:我想在topics例如topics时使用此查询。

是否可以用数组作为meta_key构建元查询?

评论

请澄清-您的意思是“主题”的存储值是一个数组吗?还是存储的值是一个字符串,您想将多个术语传递给数组中的查询?

@MathSmath,我的意思是存储的值是一个数组。

#1 楼

为查询提供可能值的数组

如果数据库中的值为字符串,并且您要向查询提供多个值:

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => array ( 'sports', 'nonprofit', 'community' ),
            'compare' => 'IN'
        )
    )
);


在序列化的数据数组中搜索特定值

如果数据库中的值是包含多个主题的数组,并且您要在该数组中搜索单个主题(请注意,该数组可以这样检索数据库中的,但以序列化的形式存在于数据库中,该字符串也是一个字符串):

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
            'compare' => 'LIKE'
        )
    )
);
并不是您希望的那样清晰的说明,但这是最好的选择。

除此之外,您唯一的选择是检索所有包含设置meta_key“主题”并手动对其进行遍历,或者换句话说,检查循环中的值并显示该条件下的帖子。

#2 楼

为了避免Johannes的回答,因为它是一个序列化的数组,所以如果您碰巧要存储用户ID之类的东西(这就是我的情况),则可能需要以不同的方式处理它。

Post meta被保存为:

array( "1", "23", "99");


所以是的,它们是整数,但通过update_post_meta它们被保存为字符串。 />
因此,您实际上正在与所需查找的序列化字符串版本进行比较。我花了好几个小时试图使类似的东西起作用,到目前为止,这是我能想到的最好的选择。

评论


serialize(strval(1))解决了我的问题,谢谢

–贝哈德
16年1月10日在20:45

今天偶然遇到了这个老答案。我喜欢你的加法。 +1

–约翰内斯·皮尔(Johannes Pille)
16-10-20在6:07

我也碰到了这一点,我的意思是我需要获取user_id不在数组中的所有帖子,但是上述解决方案不起作用,所以我做到了:'meta_query'=> array(array(' key'=>'my_meta_key','value'=>':'。$ user_id。';','compare'=>'NOT LIKE')))因为序列化时所有值都保存为:':value;'

– Bobz
18-3-19在4:29



聪明。我很精妙,不是所有的常规方法。没想到今天早上在这里找到了。道具。

–约翰内斯·皮尔(Johannes Pille)
20年8月16日在8:30

#3 楼

从@sMyles的答案中得到的另一个细微改进。这有点像update_post_meta($post_id, authorized_users', array(get_current_user_id()));的著名问题,您可以使用术语ID来设置术语,但是如果不首先将它们转换为整数,则大约有50%的机会使用这些数字作为它们来创建新术语取而代之的是名称。

这可能导致它们在序列化数组中的存储方式大不相同,就像从我的测试站点的数据库中摘录的那样: >
a:1:{i:0;s:1:"1";} // 's' for 'string', also note the double quotes
a:1:{i:0;i:1;} // 'i' for 'integer', no quotes


以上两者,当通过wp_set_object_terms()馈送时将呈现为

Array
(
    [0] => 1
)


要解决此问题,我对通过添加一个print_r()和另一个版本的查询来将值转换为整数而不是字符串,以得到meta_query

这是最终结果:

        'meta_query' => array(
            'relation' => 'OR', // Lets it know that either of the following is acceptable
            array(
                'key' => 'bcm_enm_authorized_users',
                'value'   => serialize(strval(get_current_user_id())), // Saved as string
                'compare' => 'LIKE'
            ),
            array(
                'key' => 'bcm_enm_authorized_users',
                'value'   => serialize(intval(get_current_user_id())), // Saved as integer
                'compare' => 'LIKE'
            ),
        ),


EDIT:刚意识到,此方法可能会冒着与数组索引冲突的风险,如果某人不在数组中,但他们的用户ID作为索引出现,则可能使他人非法访问材料。因此,如果您讨论了这个问题,这是可行的,但是更好的做法是确保将要搜索的任何值在保存之前都转换为字符串,以便可以使用@sMyles'方法代替。

评论


这应该是选定的答案,最可靠

–阿明
19-10-23在16:26

#4 楼

我去找约翰尼斯的答案。但是,我想改善这一点,因为使用该meta_query时,您会遇到这样的情况

搜索时,您的值为

array('sports','movies', 'sports2');




$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports',
            'compare' => 'LIKE'
        )
    )
);


,结果将同时返回'sport'和'sport2'。

要解决此问题,请将meta_query args更改为

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        array(
            'key' => 'topics',
            'value' => 'sports";',
            'compare' => 'LIKE'
        )
    )
);


这是因为该值已在数据库中序列化,并且每个项目将由分号分隔。因此,上面的args将起作用。

如果值中的项目是数字,则只需删除双引号“

$args = array(
        'post_type' => 'news',
        'meta_query' => array(
            array(
                'key' => 'topics',
                'value' => '1;',
                'compare' => 'LIKE'
            )
        )
    );


#5 楼

我今天在努力解决类似问题。
我必须查询具有多个相关用户(数组)的ACF(高级自定义字段)关系字段。

通过php更新字段后,查询没有工作。通过ACF UI对其进行更新后,查询便开始工作。

问题是,我的PHP代码将关系值设置为int值,UI将其设置为字符串值。为了确保两者都能正常工作,我现在使用此查询(适合此处的示例):

$args = array(
    'post_type' => 'news',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'topics',
            'value' => '1;',  // works for int-array
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'topics',
            'value' => '"1"',  // works for string-array
            'compare' => 'LIKE'
        ),
    )
);