如何在WordPress中查询自定义文章类型的对象类型元数据
解决方案
方法1:利用序列化数据结构做模糊匹配
WordPress会把PHP对象序列化为字符串存在postmeta表中,比如user对象序列化后会包含类似"id";i:123;的片段(id为整数的情况)。你可以直接针对这个片段做查询:
$args = array( 'post_type' => 'custom-posts', 'post_status' => 'publish', 'posts_per_page' => -1, 'order' => 'ASC', 'meta_query' => array( array( 'key' => 'user', // 这里填元数据的真实键名,不是嵌套的user.id 'value' => serialize(array('id' => $this->user_id)), 'compare' => 'LIKE' ), ) );
注意:如果id是字符串类型,序列化后的格式会变成s:X:"你的id值";,要对应调整。这种方法简单,但存在极小的误匹配概率(比如其他字段值刚好包含相同片段)。
方法2:用SQL过滤器精准查询
更可靠的方式是通过WordPress的查询钩子直接写SQL,精准匹配序列化数据中的id字段:
// 关联postmeta表 add_filter('posts_join', function($join) { global $wpdb; $join .= " INNER JOIN {$wpdb->postmeta} pm ON {$wpdb->posts}.ID = pm.post_id AND pm.meta_key = 'user'"; return $join; }); // 添加精准匹配的条件 add_filter('posts_where', function($where) { global $wpdb; $user_id = esc_sql($this->user_id); // 正则确保只匹配独立的id键,避免误匹配 $where .= " AND pm.meta_value REGEXP 's:2:\"id\";[is]:[0-9]+:\"?$user_id\"?;'"; return $where; }); // 执行查询 $query = new WP_Query($args); // 记得移除过滤器,防止影响后续查询 remove_filter('posts_join', '__return_false'); remove_filter('posts_where', '__return_false');
这种方法几乎不会出现误匹配,适合对查询准确性要求高的场景。
方法3:如果元数据是JSON格式存储
如果你的user元数据是以JSON字符串而非PHP序列化格式存储,且数据库是MySQL 5.7及以上版本,可以用JSON_CONTAINS做精准查询:
$args = array( 'post_type' => 'custom-posts', 'post_status' => 'publish', 'posts_per_page' => -1, 'order' => 'ASC', 'meta_query' => array( array( 'key' => 'user', 'value' => json_encode(array('id' => $this->user_id)), 'compare' => 'JSON_CONTAINS' ), ) );
这是最理想的方案,但依赖数据库版本和元数据的存储格式。
内容的提问来源于stack exchange,提问作者Tjerk Haaye Henricus Dames
相关产品推荐
相关产品推荐

