具有类别排除和后元“白名单”的自定义查询

时间:2013-05-07 作者:Radley Sustaire

我有两个小部件,一个显示News 而另一个则显示除新闻以外的所有内容(我们称之为第二个Blog). 博客部分当前工作正常。

这些新闻帖子要么被归类为In the News 或者自定义post metain-the-news, 设置为1。需要注意的是,并不是所有的帖子都会定义自定义帖子元。

我面临的主要问题是,我需要根据帖子的分类方式来比较帖子的元数据。

I may need to do a custom database query for this behavior, at least for the News. 是否可以执行自定义查询并将其转换为标准WP\\U查询对象?

我尝试的内容查询News.

Problem: 仅显示类别75中具有in-the-news = 1.

Desired result: 显示类别75中的所有帖子,无论in-the-news, 以及类别外的任何其他职位in-the-news = 1

query_posts(array(
  \'ignore_sticky_posts\' => true,
  \'posts_per_page\' => 3,
  \'cat\' => "75", // Only posts within category 75 (News)

  // Including posts tagged to show "In the News"
  \'meta_query\' => array(
    \'relation\' => \'OR\',
    array(
      \'key\' => \'in-the-news\',
      \'value\' => \'1\',
      \'compare\' => \'=\',
    ),
    array( 
      \'key\' => \'in-the-news\',
      \'compare\' => \'NOT EXISTS\',
      \'value\' => \'\',
    ),
  )
));
以下是Blog:

此查询似乎工作正常,显示了类别75以外的所有帖子,并使用隐藏帖子in-the-news = 1.

query_posts(array(
  \'ignore_sticky_posts\' => true,
  \'posts_per_page\' => 3,
  \'cat\' => "-75", // All posts EXCLUDING those in category 75 (News)

  \'meta_query\' => array(
    \'relation\' => \'OR\',
    array(
      \'key\' => \'in-the-news\',
      \'value\' => \'0\',
      \'compare\' => \'=\',
    ),
    array( 
      \'key\' => \'in-the-news\',
      \'compare\' => \'NOT EXISTS\',
      \'value\' => \'\',
    ),
  )
));
由于s_ha_dum 对于这些惊人的例子,这里是我使用的最后一个查询。这里的逻辑是,我们对post ID数组执行自定义MySQL查询,然后使用返回的ID执行标准WP\\U查询。

Note: 这里的逻辑比原来的帖子要复杂一些。基本上,我们最初有“新闻”和“博客”。但现在我们也有“风险”。此外in-the-news post meta已更改为show-in-blog 当我们反转功能时。我不能指望任何人从一开始就理解这一点的原因,因为即使是我也认为这很荒谬(但客户想要它,就这样吧!)

这是我对“博客”小部件的查询。“新闻”区域略有变化。我不确定是否可以清除查询。我也不确定在同一个查询中执行这么多选择是否是一个坏主意。

global $wpdb;

$query = // Splitting the SQL query to it\'s own code block for syntax highlighting!
<小时>
  SELECT `ID`
  FROM {$wpdb->posts} posts
  WHERE (

    /* Exclude posts in News (94) 
       Ignore show-in-blog option for News here, 
       as News is displayed on the same page */
    94 NOT IN ( 
      SELECT `term_taxonomy_id` 
      FROM {$wpdb->term_relationships}
      WHERE `object_id` = posts.`ID`
    )

    AND

    /* Exclude posts in Risk (96), 
       But show Risk posts that have the postmeta "show-in-blog" */
    (

      96 NOT IN ( 
        SELECT `term_taxonomy_id` 
        FROM {$wpdb->term_relationships}
        WHERE `object_id` = posts.`ID`
      )
      OR
      (
        96 IN ( 
          SELECT `term_taxonomy_id` 
          FROM {$wpdb->term_relationships}
          WHERE `object_id` = posts.`ID`
        )
        AND
        1 IN (
          SELECT `meta_value` 
          FROM {$wpdb->postmeta}
          WHERE 
          `meta_key` = \'show-in-blog\'
          AND `post_id` = posts.`ID`
        )
      ) /* OR */

    ) /* AND */

  ) /* WHERE */

  ORDER BY `post_date` DESC;
<小时>
$args = array(
  // Only include IDs returned by the above query
  \'post__in\' => $wpdb->get_col( $query ),
  \'posts_per_page\' => 10,
);

$wp_query = new WP_Query( $args );

get_template_part(\'loop\', \'frontpage\');

1 个回复
最合适的回答,由SO网友:s_ha_dum 整理而成

是否可以执行自定义查询并将其转换为标准WP\\U查询对象?

对你可以做一些像。。。

$post_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE ....");
$posts_qry = new WP_Query(array(\'post__in\'=> $posts_ids,\'orderby\' => \'post__in\'));
第二个查询将保留第一个查询的结果顺序。

我很肯定,您不能用WP_Query, 或任何其他功能。逻辑太复杂了。你需要一个JOIN 或aWHERE 条款:WP_Query 不支持。不幸的是SQL 也会很复杂,只是为了分类。

当然,完全手工编写查询是您的第一选择。没有手写我能做的最好的SQL 将是:

$post_ids = new WP_Query(array(
  \'fields\' => \'ids\',
  \'ignore_sticky_posts\' => true,
  \'posts_per_page\' => 3,
  \'cat\' => "75", // Only posts within category 75 (News)
));

$post_ids_2 = new WP_Query(array(
  \'fields\' => \'ids\',
  \'ignore_sticky_posts\' => true,
  \'posts_per_page\' => 3,
  \'post__not_in\' => $post_ids->posts,
  \'meta_query\' => array(
    array(
      \'key\' => \'_edit_lock\',
      \'value\' => \'0\',
      \'compare\' => \'=\',
    ),
  )
));
$post_ids = $post_ids->posts + $post_ids_2->posts;
$posts_qry = new WP_Query(array(\'post__in\'=> $posts_ids,\'orderby\' => \'post__in\'));
这是3个查询(哎哟),如果您担心的话,订购可能会成为一个问题。

您的另一个选项是通过几个过滤器来更改查询。这个WP_Query 争论将涉及in-the-news = 1 部分

$post_ids_v3 = new WP_Query(array(
  \'ignore_sticky_posts\' => true,
  \'posts_per_page\' => 20,
  \'my_variable\' => true,
  // Including posts tagged to show "In the News"
  \'meta_query\' => array(
    array(
      \'key\' => \'in-the-news\',
      \'value\' => \'1\',
      \'compare\' => \'=\',
    )
  )
));
请注意,您省略了类别组件,并传递了一个额外的非官方参数,名为my_variable. <我不知道这样传递额外变量是否是出于设计,所以请注意,这可能是非官方行为您将使用它将类别组件添加到带有两个过滤器的查询中。

function posts_join_wpse_98652($join,$qry) {
  global $wpdb;
  if (true === $qry->get(\'my_variable\')) {
    $join .= " JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
  }
  return $join;
}
add_filter(\'posts_join\',\'posts_join_wpse_98652\',1,2);

function posts_where_wpse_98652($where,$qry) {
  global $wpdb;
  if (true === $qry->get(\'my_variable\')) {
    $where .= " OR {$wpdb->term_relationships}.term_taxonomy_id IN (75)";
  }
  return $where;
}
add_filter(\'posts_where\',\'posts_where_wpse_98652\',1,2);
这甚至还没有经过很好的测试,但当我尝试时,它似乎起到了作用。尽管如此,这些事情可能很难纠正,也许我犯了一个错误。几乎未经测试。可能是马车。买主注意事项。不退款。

结束

相关推荐

Sort categories by meta value

如何制作一个类别列表,每个类别中有4篇最后的帖子,其中每个类别都按meta\\u值排序。例如,不按meta\\u值排序的模板是http://pastebin.com/AeH6vx9b它仅显示父类别。几天来,我在搜索与类别相关的额外字段,但找不到可行的内容。This is my best search result. 这跟我有什么关系?我不明白。有可能做我想做的事吗?