当要比较的元数据是序列化数组时,Wordpress meta_query是一个值数组?

时间:2017-05-04 17:57:59

标签: php wordpress metadata cmb2

我正在尝试运行带有值数组的meta_query,并让它搜索是否所有数据都存在于存储在序列化数组中的元值中。这可能吗?

我对查询的参数如下(注意这是嵌套在一个类中):

$args = array(
    'post_type' => $this->posttype,
    'posts_per_page' => '9',
    'paged' => $paged,
    'orderby' => 'meta_value_num',
    'order' => 'DESC',
    'meta_key' => 'lumens',
    'meta_query' => array(
        array(
            'key' => 'mount',
            'value' => array('pendant' , 'wall'),
            'compare' => 'IN'
        )

    )
);

存储的元数据的一个例子是类似于下面的序列化数组:

a:4:{i:0;s:7:"pendant";i:1;s:15:"surface-ceiling";i:2;s:4:"wall";i:3;s:14:"aircraft-cable";}

无论我尝试什么,我的查询都不会返回相应的结果。我现在意识到我可能应该将每个值存储在不同的元键中而不是存储在数组中,但是,现在已经有很多条目已经用于更改元数据。

更新

这是我的解决方法,类似于@Leander方法;由于数据库上已存在的条目数量,我不想更改序列化输入,有一件事我忘了提及,我正在使用CMB2 Developer Toolkit本地存储复选框字段作为序列化数据。

// This is pulled from a user input
$meta_queries = array('pendent' , 'wall');

// Metaqueries are passed through loop to create single entries with the like comparison operator
foreach($meta_queries as $key => $value){

    $meta_query = array(
        'key' => '_tf_' . $key,

        // Serialize the comparison value to be more exact
        'value' => serialize(strval($value)),
        'compare' => 'LIKE',
    );

}

// Generate $args array
$args = array(

    'post_type' => $this->posttype,
    'posts_per_page' => '9',
    'paged' => $paged,
    'orderby' => 'meta_value_num',
    'order' => 'DESC',
    'meta_key' => 'lumens',
    'meta_query' => $meta_queries

);

填充数据时,我没有发现太多性能问题。我想如果要处理大量数据,就必须重新设计这种方法。

2 个答案:

答案 0 :(得分:4)

刚遇到同样的问题......!

我有一些标签存储在数组/自定义字段中,并使用搜索表单查询我的帖子,其中应该允许用户搜索多个标签,所以基本上我需要将数组与另一个数组进行比较。

  

我现在意识到我可能应该将每个值存储在不同的元键中,而不是存储在数组中,但是,现在已经有很多条目可以更改元数据了。

我想这会产生相当大的开销,不建议......

方法/解决方法

我使用用户输入作为字符串,从字符串中创建一个数组以检查其大小,并根据我创建的单个LIKE比较的大小,这对我的数组的数据很好。< / p>

$tags_string = get_query_var( 'p_tags' ); // form submitted data
$tags_array = explode( ',', $tags_string ); // create array

if ( count( $tags_array ) > 1 ) { // check if more then one tag
$meta_query['p_tags']['relation'] = 'AND';

foreach($tags_array as $tag) { // create a LIKE-comparison for every single tag
    $meta_query['p_tags'][] = array( 'key' => 'YOUR_KEY', 'value' => $tag, 'compare' => 'LIKE' );
}
} else { // if only one tag then proceed with simple query
    $meta_query['p_tags'] = array( 'key' => 'YOUR_KEY', 'value' => $tags_string, 'compare' => 'LIKE' );
}

Args输出(演示)

[meta_query] => Array
        (
            [p_tags] => Array
                (
                    [relation] => AND
                    [0] => Array
                        (
                            [key] => basic_tags
                            [value] => adobe
                            [compare] => LIKE
                        )

                    [1] => Array
                        (
                            [key] => basic_tags
                            [value] => stone
                            [compare] => LIKE
                        )

                )

        )

注意:根据您的数组的大小,要查询的帖子数量等,此解决方案可能不是最有效的。

另一种方法可能是WordPress查询的FIND_IN_SET扩展,see this gist

感谢有关性能或提高代码质量的任何意见。

答案 1 :(得分:0)

  

现在更改元数据的条目太多了

然后运行脚本(PHP脚本或MySQL直接)并创建正确的meta_key =&gt; meta_value对,然后删除序列化列。序列化数据只有在要检索的情况下才应存储在数据库中。如果你很懒,但仍希望只有一列,则将数据存储为JSON,然后将它们作为JSON查询(现代版本的MySQL允许从JSON类型的列中查询json数据)。祝你好运。

但是如果你坚持并保持数据序列化,我向你保证,你或任何维护你项目的人都会为你需要实现的每个相关的小功能而不断敲打他们的头脑。