如何创建带有数组作为meta_field的meta_query?


16

这是我的查询的参数:

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

topics为字符串时有效,但为数组时无效。我希望这个查询在topics例如array( 'sports', 'nonprofit', etc. )

有没有一种方法可以使用数组作为meta_key构建元查询?


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

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

Answers:


31

向查询提供可能值的数组

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

$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'
        )
    )
);

使用“ LIKE”作为比较值并不像您希望的那样清晰明了,但它是最好的选择。

紧接着,您唯一的其他选择是检索所有设置了meta_key “ topics”的帖子,并手动对其进行遍历,或者换句话说,检查循环中的值并在上述条件下显示帖子。


14

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

发布元被保存为:

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

所以是的,它们是整数,但是通过update_post_meta它们它们被保存为字符串。

'meta_query' => array(
            array(
                    'key'     => 'my_meta_key',
                    'value'   => serialize( strval( 1 ) ),
                    'compare' => 'LIKE'
                )
            )

因此,您实际上正在与要查找的序列化字符串版本进行比较。我花了好几个小时试图使类似的东西起作用,到目前为止,这是我能想到的最好的方法。


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

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

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

4

@sMyles的回答还有一点改进。

我曾经遇到过ID既存储为字符串(例如从表单输入中获取)又存储为整数(例如update_post_meta($post_id, authorized_users', array(get_current_user_id()));)的情况。这有点像一个众所周知的问题wp_set_object_terms(),您可以在其中使用术语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

以上两种情况在馈入时print_r()都会呈现为

Array
(
    [0] => 1
)

为了解决这个问题,我meta_query通过添加一个relation和其他版本的查询(将值转换为整数而不是字符串)对做了一些微调。

这是最终结果:

        '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'
            ),
        ),

编辑:刚意识到,此方法可能会与数组索引发生冲突,如果某人不在数组中,但他们的用户ID却显示为索引,则可能允许他人非法访问材料。因此,虽然这个作品,如果你有这个问题的讨论,更好的做法是,以确保您要搜索铸造成之前保存,这样就可以使用@sMyles'的方法,而不是字符串的任何值。


这应该是最可靠的选择答案
Amin

2

我去找约翰内斯的答案。但是,我想改善这一点,因为使用该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'
            )
        )
    );

1

我今天在努力做类似的事情。我必须查询具有多个相关用户(数组)的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'
        ),
    )
);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.