WP_Query and NULL meta keys

时间:2017-03-09 作者:Kosta Kondratenko

我有一堆带有两个元键的自定义帖子-\\u claired和\\u average\\u rating。只有当有人在帖子上留下评分时,\\u average\\u rating才会添加为元键,而只有当用户声明列表时,\\u claimed meta key才会设置为1,否则列表中没有\\u claimed或\\u average\\u rating的值。

我想做的是将列表按如下方式排列:-显示首先按平均审核排序的所有已申请的列表(从高到低)-显示在此之后未申请的所有列表,按平均审核排序(从高到低)

以下MySQL代码是提供给我的,当我在phpMyAdmin中测试时,它似乎可以工作:

SELECT p.`ID` , IFNULL( pm.`meta_value` , 0 ) AS claimed, IFNULL( pm2.`meta_value` , 0 ) AS averageRating
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON p.ID = pm.`post_id` 
AND pm.`meta_key` =  \'_claimed\'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.`post_id` 
AND pm2.`meta_key` =  \'_average_rating\'
ORDER BY claimed DESC , averageRating DESC  
我使用的插件要求在WP\\U查询中创建过滤器-如果您感兴趣,该插件称为FacetWP,下面是我目前拥有的过滤器示例代码,可以让您了解所需的内容:

--

function my_facetwp_sort_options( $options, $params ) {
    $options[\'rating\'] = array(
        \'label\' => \'Ripoff\',
        \'query_args\' => array(
         \'meta_query\' => array(
                array(
                    \'key\' => \'_average_rating\',
                    \'value\' => 2,
                    \'compare\' => \'<=\',
                    \'type\' => \'NUMERIC\',
                )
            ),
            \'orderby\' => \'meta_value_num\', // sort by numerical custom field
            \'meta_key\' => \'_average_rating\', // required when sorting by custom fields
            \'order\' => \'DESC\' // descending order
        )
    );

    $options[\'review_desc\'] = array(
        \'label\' => \'Average Review (highest)\',
        \'sort_custom\' => true,
        \'query_args\' => 
        array(
  \'meta_query\' => array(
  \'relation\' => \'OR\',
    array(
      \'key\' => \'_claimed\',
      \'value\' => 1,
    \'compare\' => \'=\',
     \'type\' => \'NUMERIC\'
    ),
    array(
      \'key\' => \'_average_rating\'
    )
  )
)
    );

    $options[\'recent_review\'] = array(
        \'label\' => \'Most Recent Reviews\',
        \'query_args\' => array(
            \'orderby\' => \'meta_value_num\',
            \'meta_key\' => \'date_reviewed\',
            \'order\' => \'DESC\',
        )
    );

    return $options;

}
add_filter( \'facetwp_sort_options\', \'my_facetwp_sort_options\', 10, 2 );
--如果感兴趣,请在此插入文档:https://facetwp.com/documentation/facetwp_sort_options/

为了生成我所需的MySQL查询(我知道这是可行的),我添加了以下代码:

<小时>

function mysite_custom_sort( $orderby, $wp_query ) {
  if ( isset( $wp_query->query_vars[\'sort_custom\'] ) ) {
    $orderby = \'mt1.meta_value ASC, mt2.meta_value DESC\';
  }
  return $orderby;
}
function edit_posts_join_paged($join_paged_statement) {
    if ( isset( $wp_query->query_vars[\'sort_custom\'] ) ) {
    $join_paged_statement = "LEFT JOIN wp_postmeta pm ON p.ID = pm.`post_id` 
AND pm.`meta_key` =  \'_claimed\'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.`post_id` 
AND pm2.`meta_key` =  \'_average_rating\'";
    }
    return $join_paged_statement;   
}

add_filter( \'posts_orderby\', \'mysite_custom_sort\', 10, 2 );
添加过滤器(\'posts\\u join\\u paged\',\'edit\\u posts\\u join\\u paged\')我的理解是,这会将自定义orderby和JOIN语句添加到WP\\U查询中。但是,我不知道如何在WP\\U查询中重新创建以下代码:

SELECT p.`ID` , IFNULL( pm.`meta_value` , 0 ) AS claimed, IFNULL( pm2.`meta_value` , 0 ) AS averageRating
请注意,在上面的示例中,它将\\u claired和\\u average\\u rating的所有值设置为0-以便显示所有内容。我如何使用WP\\u Query做到这一点,尽管在插件如何按照我上面列出的要求工作的范围内,这些要求是:

显示所有先申请的物品,按平均审查(从高到低)排序

  • 显示所有在此之后未申请的物品,按平均审查(从高到低)排序
  • 对此问题的任何意见都将不胜感激。

    1 个回复
    SO网友:Ben Casey

    我不相信有一种方法可以在WordPress中同时完成两个查询。

    如果您现有的过滤器正在工作,并且没有将原始用户输入注入到数据库查询中,那么问题是什么?这正是过滤器的作用所在。

    如果您不喜欢使用过滤器,那么可以对数据库进行两次单独的查询,以获得相同的结果。这意味着性能会受到较小的影响(取决于数据库的大小),但这可以通过使用transients API缓存结果来缓解。

    EDIT

    如果您需要为所有已发布的帖子添加一个密钥,下面这样的操作应该可以实现,它将遍历所有没有元密钥的产品_average_rating 并添加0中的一个未测试

    我通常是基于admin中的一个秘密$\\u GET参数来执行此操作的,在它运行后删除它。

    $query = new WP_Query( [
        \'post_type\'      => \'product\',
        \'posts_per_page\' => -1,
        \'post_status\'    => \'publish\',
        \'meta_query\'     => [
            [
                \'key\'     => \'_average_rating\',
                \'compare\' => \'NOT EXISTS\'
            ]
        ]
    ] );
    
    foreach( $query->posts as $post ){
        update_post_meta( $post->ID, \'_average_rating\', 0 );
    }
    

    相关推荐

    Testing Plugins for Multisite

    我最近发布了一个WordPress插件,它在单个站点上非常有效。我被告知该插件在多站点安装上不能正常工作,我理解其中的一些原因。我已经更新了代码,现在需要一种方法来测试更新后的代码,然后才能转到实时客户的多站点安装。我有一个用于测试的WordPress安装程序的单站点安装,但需要在多站点安装上进行测试。根据我所能找到的唯一方法是在网络上至少有两个站点来安装整个多站点安装,以测试我的插件。设置WordPress的整个多站点安装是插件开发人员的唯一/首选方式,还是有更快的测试环境可用。