使用wordpress帖子的酒店价格比较逻辑

时间:2012-11-17 09:26:16

标签: wordpress comparison logic

考虑一下情况,我发布了元字段:

  1. MIN_PRICE
  2. MAX_PRICE
  3. 所以每个帖子都有这两个字段,value可以是从非零到1000的任何整数。

    让我们举一个例子:

    1. 发布#1 min_price = 5; max_price = 100
    2. 发布#2 min_price = 50; max_price = 150
    3. 我想制作自定义订单逻辑以与query_posts一起使用。因此,用户可以选择价格范围并查看包含所选值的帖子。

      现在,如果我只有1个价格和1个字段,那么很容易让用户选择价格范围并获得属于这些范围的帖子,如下所示:

      query_posts( array(
          'post_type' => 'product',
          'meta_query' => array(
              array(
                  'key' => 'price',
                  'value' => array( 100, 200 ),
                  'compare' => 'BETWEEN',
                  'type' => 'numeric',
              )
          )
      ) );
      

      所以这里每个价格在100-200之间的帖子都是可见的。

      但我有一系列的价值观......我认为这样可行:

      query_posts( array(
          'post_type' => 'product',
          'meta_query' => array(
              array(
                  'key' => 'min_price',
                  'value' => array( 100, 200 ),
                  'compare' => 'BETWEEN',
                  'type' => 'numeric',
              ),
                  array(
                  'key' => 'max_price',
                  'value' => array( 100, 200 ),
                  'compare' => 'BETWEEN',
                  'type' => 'numeric',
              )
          )
      ) );
      

      这里客户选择范围100< - > 200 帖子#1和帖子#2的值都在这个范围内,所以访问者会对它们都感兴趣。不幸的是,我的查询逻辑排除了它们。

      我的大脑现在不能正常工作,所以我错过了一些简单的东西。任何提示?

2 个答案:

答案 0 :(得分:1)

我现在知道你的方式应该有效,除了麦克纳布可能是正确的(这里有很多例子:http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters)但我会保留原来的答案。有人可能会发现它对非标准的东西很有用。

我不知道您是否可以使用查询帖子参数执行此操作,但我在源代码中查找了它,这就是查询的外观:

SELECT $found_rows $distinct $fields 
FROM $wpdb->posts $join 
WHERE 1=1 $where 
$groupby 
$orderby 
$limits

这些是与相关查询变量对应的过滤器:

$where = apply_filters_ref_array('posts_where', array( $where, &$this ) );
$join = apply_filters_ref_array('posts_join', array( $join, &$this ) );

这意味着问题可以简化为SQL:

function postmeta_join( $join )
{
    $join .= "
    LEFT JOIN $wpdb->postmeta AS max_price ON max_price.meta_key = 'max_price'
    LEFT JOIN $wpdb->postmeta AS min_price ON min_price.meta_key = 'min_price'";
    return $join;
}

function filter_prices($where)
{
    $where .= " AND max_price.max_price BETWEEN 100, 200 AND min_price.min_price BETWEN 100, 200";
    return $where;
}

add_filter( 'posts_where', 'filter_prices' );
add_filter( 'posts_join', 'postmeta_join' );

现在我不是SQL专家,因此可能存在问题。但如果你没有得到任何其他答案,你可以玩这个。 (顺便说一下,你可能想要在完成它们后删除过滤器。)

答案 1 :(得分:1)

你做了什么应该工作,但你错过了'关系'参数。它应该是;

                'meta_query' => array(
                    'relation' => 'AND',
                    array(
                        'key' => 'min_price',
                        'value' => array( 100, 200 ),
                        'compare' => 'BETWEEN',
                        'type' => 'numeric',
                    ),
                        array(
                        'key' => 'max_price',
                        'value' => array( 100, 200 ),
                        'compare' => 'BETWEEN',
                        'type' => 'numeric',
                    )
                )

另外需要注意的是,在第一个实例中,meta_id是'price',在第二个实例中,你使用'min_price'和'max_price'。这些肯定已经确定了吗?

我之所以提到这一点是因为最近我在这些带有多个子数组的meta_queries和AND关系上遇到了困难,其中值已经由用户以表单形式提交(就像我对你的问题的理解一样)。存在一个问题,即如果数组中的项具有空值,则查询不起作用。这是由scribu修复的;

http://core.trac.wordpress.org/ticket/18158

但我根本无法工作。撕掉我的头发。我最终检查提交的值以查看是否有一个,然后单独创建数组。如果$ min_array或$ max_array为NULL,则查询将起作用,但如果meta_values中的任何一个为NULL并且按照您的方式构建它,则查询将不起作用。我希望这是有道理的,我的代码在下面;

                if ($min_price) {
                  $min_array = array('key' => 'min_price','value' => $min_price, 'value' => '=', 'type' => 'numeric');
                }

                if ($max_price) {
                  $max_array = array('key' => 'max_price','value' => $max_price, 'value' => '=', 'type' => 'numeric');
                }

                'meta_query' => array(
                    'relation' => 'AND',
                    $min_array,
                    $max_array
                )