1

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

  1. 最低价格
  2. Max_Price

所以每个帖子都有这两个字段,值可以是从非零到 1000 的任何整数。

举个例子:

  1. 发布#1 min_price = 5; 最大价格 = 100
  2. 发布#2 min_price = 50; 最大价格 = 150

我想制作自定义订单逻辑以与 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 的值都在此范围内,因此访问者会对它们都感兴趣。不幸的是,我的查询逻辑将它们排除在外。

我的大脑现在不能很好地工作,所以我错过了一些简单的东西。有什么提示吗?

4

2 回答 2

1

我现在知道你的方法应该可行,除了 McNab 可能是正确的(这里有很多例子: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 专家,所以这可能存在问题。但如果你没有得到任何其他答案,你可以玩这个。(顺便说一句,您可能想在完成过滤器后删除它们。)

于 2012-11-17T11:42:33.503 回答
1

您所做的应该可以工作,但是您错过了“关系”参数。它应该是;

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

另一件要注意的是,在第一个实例中,meta_id 是“price”,而在第二个实例中,您使用的是“min_price”和“max_price”。这些确定是设置好的吗?

我之所以提到这一点,是因为最近我很难处理这些带有多个子数组的元查询以及用户在表单中提交值的 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
                ) 
于 2012-11-17T11:54:38.880 回答