【问题标题】:Group by wordpress posts by meta value按元值按wordpress帖子分组
【发布时间】:2021-03-13 15:38:03
【问题描述】:

我的 wordpress 数据库中有大约 2000 个 woocommerce 产品,每个产品都有一个名为 place 的 ACF 选择字段,其值为 local 或 regional .

我的目标是按地点元字段对每个产品进行分组,所以我认为以下代码可以完成这项工作:

class Search
{
  public function __construct() 
  {
      add_action("pre_get_posts", [$this, "filterProducts"]);
      add_filter('posts_groupby', [$this, 'groupByFilter'] );
  }
  public function filterProducts($query){
    // ... code
    // This where i alter que query 
   // .. code
   return $query;
  }
  public function groupByFilter($groupby)
  {
     global $wpdb;
     return $wpdb->postmeta . ".meta_key = 'place'";
  }
}

但是,这不起作用,只输出一种产品,而预期的结果是:

-- 本地

  • 产品
  • 产品

-- 地区性

  • 产品
  • 产品

我知道每个产品的 foreach 都是一个解决方案,但出于性能原因,我希望通过主查询直接处理它。

注意:如果有帮助,我会使用木材,并且在 search.php 文件中我有这段代码:

$context = Timber::get_context();
$context["posts"] = new \Timber\PostQuery();
// print the results
dump($context['posts']);

更新: sql 结果输出这个查询:

SELECT 6288gjvs_posts.* FROM 6288gjvs_posts 
WHERE 1=1  
AND 6288gjvs_posts.post_type = 'product'  
AND (6288gjvs_posts.post_status = 'publish' 
OR 6288gjvs_posts.post_status = 'acf-disabled' 
OR 6288gjvs_posts.post_status = 'complete' 
OR 6288gjvs_posts.post_status = 'paid' 
OR 6288gjvs_posts.post_status = 'confirmed' 
OR 6288gjvs_posts.post_status = 'unpaid' 
OR 6288gjvs_posts.post_status = 'pending-confirmation' 
OR 6288gjvs_posts.post_status = 'cancelled' 
OR 6288gjvs_posts.post_status = 'private') 
GROUP BY 6288gjvs_postmeta.meta_key = 'place' 
ORDER BY 6288gjvs_posts.menu_order, RAND(1348526234)

将其复制并粘贴到 phpmyadmin 上并显示错误输出: #1054 - 组声明中不知道冠军 '6288gjvs_postmeta.meta_key'

所以我离开加入帖子元:

SELECT 6288gjvs_posts.post_title, 6288gjvs_posts.ID, 6288gjvs_postmeta.post_id  
FROM 6288gjvs_posts  
LEFT JOIN 6288gjvs_postmeta 
ON 6288gjvs_posts.ID = 6288gjvs_postmeta.post_id 
AND 6288gjvs_posts.post_type = 'product'  
GROUP BY 6288gjvs_postmeta.meta_key = 'place'

没有成功

更新 2

你好,所以最后我选择了两个查询,我没有找到任何解决方案,现在我必须在一页中管理两个分页:(。如果有人找到解决方案,我总是跟进这篇文章,可能会有用为他人。

感谢您的帮助

【问题讨论】:

标签: wordpress woocommerce


【解决方案1】:

如果你想通过元键过滤你的帖子,你一定要看看WP_Meta_Query。

就像您在“pre_get_posts”过滤器中使用“tax_query”一样,您应该在主查询中添加另一个查询,如下所示:

$meta_query[] = array(
                'key'     => 'place',
                'value'   => 'your_value',
                'compare' => '=',
        );
$query->set('meta_query', $meta_query);

我希望你觉得这很有用,它可以解决你的问题。

【讨论】:

  • 您好,谢谢您,我添加的tax_query 并不重要,只是说我更改了块内的查询,但是从您的代码中,我应该在“your_value”中添加什么? “本地”或“区域”值?
  • 将“your_value”替换为区域性以获取具有 place=regional 的帖子,并将具有 meta place=local 的帖子替换为 local
  • 谢谢,但例外的结果是按“本地”和“区域”分组的帖子列表,它不是一个简单的元值过滤器,我想作为输出分组结果。
  • 我不确定 wordpress 查询是否有 GROUP BY 语句的选项。如果不是,并且您希望将输出分组,则必须创建自定义 SQL 查询并使用 $wpdb->get_results($your_custom_sql) 运行它,或者尝试使用 php 手动对帖子进行分组,而不是直接对查询结果进行分组.第二种解决方案不是最有效的,因为您必须获取每个帖子的帖子元数据,然后检查值。
  • 我更新了帖子,没有成功离开加入帖子元,您对此有何建议?
【解决方案2】:

使用WP_Query 获取帖子更容易且明智,而不是修改可能影响其他帖子类型和查询的 SQL 代码。在您获得 WooCommerce 产品的场景中,请使用 WC_Product_Query。下面是一个示例,它将为您提供带有 meta_key = place 的产品

function get_xx_products()
{
    $args = array(
        'my_custom_var'         => array(
            array(
                'key'           =>  'place',
                'value'         =>  '',
                'meta_compare'  =>  'EXISTS'
            )
        ),
        'status'                => 'publish'
    );
    return wc_get_products($args);
}

function hook_my_custom_var($query, $query_vars)
{
    if (!empty($query_vars['my_custom_var'])) {
        $query['meta_query'] = $query_vars['my_custom_var'];
    }
    
    return $query;
}
add_filter('woocommerce_product_data_store_cpt_get_products_query', 'hook_my_custom_var', 10, 2);

您可以在此处阅读更多相关信息 - https://github.com/woocommerce/woocommerce/wiki/wc_get_products-and-WC_Product_Query

【讨论】:

  • 你好,资料很丰富,谢谢,我查一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
  • 2011-07-20
  • 2017-06-29
相关资源
最近更新 更多