WordPress:排除带有 meta_query 的帖子 - 并非每个帖子都有 meta_field
WordPress: Exclude posts with meta_query - Not every posts has the meta_field
我想排除所有具有自定义元字段特定值的 post。
问题是,并不是每个 post 都有这个元字段。
我的代码如下所示(工作循环的摘录):
// WP_Query arguments
$args = array (
'post_parent' => $parentid,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_type' => array( 'page' ),
'meta_query' => array(
array(
'key' => 'hide',
'value' => 1,
'compare' => '!='
)
)
);
并非每个 post 都会使用字段 "hide"。一些 posts 返回 NULL。
所以我认为,循环因此无法正常工作?!
这是正确的吗?是否每个 posts 都有该键的值?
尝试按照以下代码片段检查您的 SQL 声明。
$customPosts = new WP_Query($yourArgs);
echo "Last SQL-Query: {$customPosts->request}";
这是一篇旧文章 post,但无论如何都要回答。此问题中的元查询只会 return 具有该元键的 post 结果。对于根本没有该元键的 return post,您需要一个额外的元查询。示例:
// WP_Query arguments
$args = array (
'post_parent' => $parentid,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_type' => array( 'page' ),
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'hide',
'value' => 1,
'compare' => '!='
),
array(
'key' => 'hide',
'compare' => 'NOT EXISTS'
)
)
);
注意“关系”的使用和具有比较值 'NOT EXISTS' 的第二个元查询。
更新我目前如何处理这种情况:
我似乎 运行 越来越多地遇到这种情况,并且我开发了一种处理它的方法,可以更快地 SQL 查询。每当有问题的 post 类型中的 post 被保存时,我都会更新满足我的查询条件的 post ID 列表并将其存储在 WP 选项中。然后当我的查询是 运行 时,我得到这个列表,然后将它放在 'include' 或 'exclude' 查询参数中,具体取决于这是白名单还是黑名单。
这确实增加了一些代码,但这里的好处在于性能,如果您有其他元查询也需要 运行,还可以消除一些复杂性。下面是黑名单的一些示例代码,这也可以适用于白名单。
class Example_Meta_Blacklist
{
public function init()
{
/*
* Trigger whenever post is saved, you could also trigger on save_post_{$post->post_type}
* If you are using Advanced Custom Fields, you may need to use acf/save_post
*/
add_action( 'save_post', [ $this, 'update_my_custom_post_type_blacklist' ] );
/*
* One time use function to create an initial list if needed. Remove if not.
*/
add_action( 'wp', [ $this, 'create_initial_my_custom_post_type_blacklist' ] );
}
/*
* Add or remove post ids from our list whenever the post is saved
*/
public function update_my_custom_post_type_blacklist( $post_id )
{
if ( 'my_custom_post_type' != get_post_type( $post_id ) ) {
return;
}
$my_custom_post_type_blacklist = get_option( 'my_custom_post_type_blacklist', [] );
$key = array_search( $post_id, $my_custom_post_type_blacklist );
$meta_key_in_question = get_post_meta( $post_id, 'meta_key_in_question', true );
if ( ! $meta_key_in_question && $key !== false ) {
unset( $my_custom_post_type_blacklist[ $key ] );
} else if ( $meta_key_in_question && $key === false ) {
$my_custom_post_type_blacklist[] = $post_id;
}
update_option( 'my_custom_post_type_blacklist', $my_custom_post_type_blacklist, true );
}
/*
* When I run into this issue, there are usually already some existing
* posts, so I need to run this code one-time to create my initial list
* This code would be run by visiting your site with ?gocode=myuniquegocode
* at the end of the URL. The function and action hook can then be removed.
*/
public function create_initial_my_custom_post_type_blacklist()
{
if ( ! isset( $_GET['gocode'] ) || 'myuniquegocode' != $_GET['gocode'] ) {
return;
}
$clients = get_posts([
'posts_per_page' => -1,
'post_type' => 'my_custom_post_type',
'post_status' => 'publish',
'fields' => 'ids',
'meta_key' => 'the_meta_key_in_question',
'meta_value' => 'the_meta_value_in_question',
'meta_compare' => '='
]);
update_option( 'my_custom_post_type_blacklist', $clients, true );
}
}
add_action( 'plugins_loaded', [ new Example_Meta_Blacklist, 'init' ] );
然后在 posts 的查询中:
$my_query = new WP_Query( [
'post_type' => 'my_custom_post_type',
'post_status' => 'publish',
'exclude' => get_option( 'my_custom_post_type_blacklist', [] )
] );
另一种方法:
// WP_Query arguments
$args = array (
'post_parent' => $parentid,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_type' => array( 'page' ),
'meta_query' => array('0' => array('key' => 'hide', 'value' => '1', 'compare' => 'NOT EXISTS')
)
);
我想排除所有具有自定义元字段特定值的 post。 问题是,并不是每个 post 都有这个元字段。
我的代码如下所示(工作循环的摘录):
// WP_Query arguments
$args = array (
'post_parent' => $parentid,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_type' => array( 'page' ),
'meta_query' => array(
array(
'key' => 'hide',
'value' => 1,
'compare' => '!='
)
)
);
并非每个 post 都会使用字段 "hide"。一些 posts 返回 NULL。 所以我认为,循环因此无法正常工作?!
这是正确的吗?是否每个 posts 都有该键的值?
尝试按照以下代码片段检查您的 SQL 声明。
$customPosts = new WP_Query($yourArgs);
echo "Last SQL-Query: {$customPosts->request}";
这是一篇旧文章 post,但无论如何都要回答。此问题中的元查询只会 return 具有该元键的 post 结果。对于根本没有该元键的 return post,您需要一个额外的元查询。示例:
// WP_Query arguments
$args = array (
'post_parent' => $parentid,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_type' => array( 'page' ),
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'hide',
'value' => 1,
'compare' => '!='
),
array(
'key' => 'hide',
'compare' => 'NOT EXISTS'
)
)
);
注意“关系”的使用和具有比较值 'NOT EXISTS' 的第二个元查询。
更新我目前如何处理这种情况:
我似乎 运行 越来越多地遇到这种情况,并且我开发了一种处理它的方法,可以更快地 SQL 查询。每当有问题的 post 类型中的 post 被保存时,我都会更新满足我的查询条件的 post ID 列表并将其存储在 WP 选项中。然后当我的查询是 运行 时,我得到这个列表,然后将它放在 'include' 或 'exclude' 查询参数中,具体取决于这是白名单还是黑名单。
这确实增加了一些代码,但这里的好处在于性能,如果您有其他元查询也需要 运行,还可以消除一些复杂性。下面是黑名单的一些示例代码,这也可以适用于白名单。
class Example_Meta_Blacklist
{
public function init()
{
/*
* Trigger whenever post is saved, you could also trigger on save_post_{$post->post_type}
* If you are using Advanced Custom Fields, you may need to use acf/save_post
*/
add_action( 'save_post', [ $this, 'update_my_custom_post_type_blacklist' ] );
/*
* One time use function to create an initial list if needed. Remove if not.
*/
add_action( 'wp', [ $this, 'create_initial_my_custom_post_type_blacklist' ] );
}
/*
* Add or remove post ids from our list whenever the post is saved
*/
public function update_my_custom_post_type_blacklist( $post_id )
{
if ( 'my_custom_post_type' != get_post_type( $post_id ) ) {
return;
}
$my_custom_post_type_blacklist = get_option( 'my_custom_post_type_blacklist', [] );
$key = array_search( $post_id, $my_custom_post_type_blacklist );
$meta_key_in_question = get_post_meta( $post_id, 'meta_key_in_question', true );
if ( ! $meta_key_in_question && $key !== false ) {
unset( $my_custom_post_type_blacklist[ $key ] );
} else if ( $meta_key_in_question && $key === false ) {
$my_custom_post_type_blacklist[] = $post_id;
}
update_option( 'my_custom_post_type_blacklist', $my_custom_post_type_blacklist, true );
}
/*
* When I run into this issue, there are usually already some existing
* posts, so I need to run this code one-time to create my initial list
* This code would be run by visiting your site with ?gocode=myuniquegocode
* at the end of the URL. The function and action hook can then be removed.
*/
public function create_initial_my_custom_post_type_blacklist()
{
if ( ! isset( $_GET['gocode'] ) || 'myuniquegocode' != $_GET['gocode'] ) {
return;
}
$clients = get_posts([
'posts_per_page' => -1,
'post_type' => 'my_custom_post_type',
'post_status' => 'publish',
'fields' => 'ids',
'meta_key' => 'the_meta_key_in_question',
'meta_value' => 'the_meta_value_in_question',
'meta_compare' => '='
]);
update_option( 'my_custom_post_type_blacklist', $clients, true );
}
}
add_action( 'plugins_loaded', [ new Example_Meta_Blacklist, 'init' ] );
然后在 posts 的查询中:
$my_query = new WP_Query( [
'post_type' => 'my_custom_post_type',
'post_status' => 'publish',
'exclude' => get_option( 'my_custom_post_type_blacklist', [] )
] );
另一种方法:
// WP_Query arguments
$args = array (
'post_parent' => $parentid,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_type' => array( 'page' ),
'meta_query' => array('0' => array('key' => 'hide', 'value' => '1', 'compare' => 'NOT EXISTS')
)
);