问题描述
我正在开发一个项目,在该项目中,我创建一个自定义帖子类型,并通过与自定义帖子类型相关联的元框输入自定义数据。无论什么原因,我决定以这样一种方式对元框进行编码,即每个元变量中的输入都是数组的一部分。例如,我正在存储经度和纬度:
<p>
<label for="latitude">Latitude:</label><br />
<input type="text" id="latitude" name="coordinates[latitude]" class="full-width" value="" />
</p>
<p>
<label for="longitude">Longitude:</label><br />
<input type="text" id="longitude" name="coordinates[longitude]" class="full-width" value="" />
</p>
无论什么原因,我喜欢为每个 metabox 进行一个单独的后期记录输入的想法。在 save_post
钩子上,我保存数据如下:
update_post_meta($post_id, '_coordinates', $_POST['coordinates']);
我这样做是因为我有三个 metaboxes,我喜欢每个帖子都有 3 个 postmeta 值; 然而,我现在已经意识到了一个潜在的问题。我可能希望使用 WP_Query 只能根据这些元值提取某些帖子。例如,我可能想要获得纬度值大于 50 的所有帖子。如果我在数据库中单独拥有这些数据,也许使用 latitude
键,我会做一些类似于
$args = array(
'post_type' => 'my-post-type',
'meta_query' => array(
array(
'key' => 'latitude',
'value' => '50',
'compare' => '>'
)
)
);
$query = new WP_Query( $args );
由于我有纬度作为_coordinates
postmeta 的一部分,所以这不行。
所以,我的问题是,有没有办法利用 meta_query
查询序列化的数组,就像我在这种情况下?
最佳解决方案
不,不可能。
我强烈建议您取消对您的数据进行排序,并修改保存程序。与此类似的应将数据转换为新格式:
$args = array(
'post_type' => 'my-post-type',
'meta_key' => '_coordinates',
'posts_per_page' => -1
);
$query = new WP_Query( $args );
if($query->have_posts()){
while($query->have_posts()){
$query->the_post();
$c = get_post_meta($post->id,'_coordinates',true);
add_post_meta($post->ID,'_longitude',$c['longitude']);
add_post_meta($post->ID,'_latitude',$c['latitude']);
delete_post_meta($post->ID,'_coordinates',$c);
}
}
然后,您可以根据需要使用单个键进行查询
您可能可以查询部分日期块,但这将是超级不可靠,昂贵,缓慢,非常脆弱,有许多边案例。序列化数据不适用于 SQL 查询,并且不会以常规和常量的方式进行格式化。
MySQL 将其视为一个字符串,不能将其分解成结构化数据。将其分解成结构化数据正是上面的代码
如果您需要存储多个经度和多纬度,则可以存储多个具有相同名称的后期元数据。只需使用 get_post_meta
的第三个参数,它将全部作为数组返回
次佳解决方案
当将条目序列化到 WP 数据库中时,您将无法以任何有效的方式查询您的数据。
您认为通过序列化实现的整体效能节省和收益在任何主要程度上都不会显着。您可能会获得略小的数据库大小,但是如果您查询这些字段并尝试以任何有用的,有意义的方式进行比较,则 SQL 事务的成本将变得很大。
相反,保存序列化您不想查询的数据的性质,而只能通过直接的 WP API 调用 get_post_meta()
以被动方式进行访问 – 从该函数可以解压缩序列化条目以访问其数组属性。
实际上分配了 true 的值作为 in;
$meta = get_post_meta( $post->ID, 'key', true );
将数据作为数组返回,可供您按照常规进行迭代。
您可以专注于其他数据库/站点优化,如缓存,CSS 和 JS 缩小,并且如果需要,可以使用像 CDN 这样的服务。要命名几个…. WordPress Codex 是一个很好的起点,以更多地发现这个主题:这里
第三种解决方案
我也遇到这种情况。在这里我做了什么
$args = array(
'post_type' => 'my-post-type',
'meta_query' => array(
array(
'key' => 'latitude',
'value' => sprintf(':"%s";', $value),
'compare' => 'LIKE'
)
)
);
希望这个帮助
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。