Make WordPress Core

Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#34266 closed feature request (wontfix)

Support for ranges in WP_Query

Reported by: dziudek's profile dziudek Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Query Keywords: 2nd-opinion
Focuses: Cc:

Description

Hello,

I think that WP_Query should support a very simple feature for all comparable values - ranges.

I mean that WP_Query should support syntax like:

'post__in' => '123..678' // get posts with ID >= 123 and ID <= 678

It could use the BETWEEN keyword from MySQL. The BETWEEN keyword is just a syntax feature which should behave as a normal comparing operators with the similar performance (compare: http://stackoverflow.com/questions/4382892/whats-mysqls-between-performance-over).

Example implementation for the post__in parameter:

} elseif ( $q['post__in'] ) {
    if ( is_string( $q['post__in'] ) ) {
        $post__in = array_map( 'absint', explode('..', $q['post__in']));
        $where .= " AND {$wpdb->posts}.ID BETWEEN {$post__in[0]} AND {$post__in[1]}";
		} else {
        $post__in = implode(',', array_map( 'absint', $q['post__in'] ));
        $where .= " AND {$wpdb->posts}.ID IN ($post__in)";
    }
}

Optionally the following syntax could be also supported (but it will increase amount of code necessary for parsing the new syntax):

'post__in' => '123..' // get posts with ID >= 123
'post__in' => '..123' // get posts with ID <= 123

Change History (7)

#1 @akibjorklund
10 years ago

What are some common use cases for this enhancement? For post date and custom fields there already is an implementation of BETWEEN. You example of post__id does on seem like a very common requirement to me. It is also relatively easy to just add a custom where clause with a filter when needed.

#2 @boonebgorges
10 years ago

Hi dziudek - thanks for the interesting suggestion!

Like akibjorklund, I'm curious about the use cases for this. I would think that the more common use for "between" logic would use *dates* as the endpoints. This is already possible:

$q = new WP_Query( array(
    'date_query' => array(
        'column' => 'post_date_gmt',
        'relation' => 'AND',
        array(
            'after' => '2015-01-01 00:00:00',
        ),
        array(
            'before' => date( 'Y-m-d H:i:s' ),
        ),
    ),
) );

or whatever. Of course, this requires that you know the dates in question, and that your data is regular enough that dates will be a sufficient sorting mechanism.

#3 @dziudek
10 years ago

@akibjorklund - in fact it is a syntax sugar for WP_Query, but in my opinion very useful - instead of writing nested arrays with clauses you can put it inside one simple string.

Regarding the use cases:

  • when you have a page with a lot of posts it is easier to specify the start/end ID than full date of post (with hours and minutes)
  • it is a good replacement for case when we have lot of IDs in the postin - it means less code,
  • show posts which have ID higher/lower than X - it means a lot of less code than using date conditionals with syntax like '0..123' or '123..1000000'
  • show posts from specific time range in an easy way like 'post_date' => '2015-01-01..2015-10-01'

And please remember - I don't want to replace some features - just add simpler syntax for it :)

#4 @akibjorklund
10 years ago

Makes sense. The nested arrays really can get pretty complex to write and not so easy to read and anything that will make it simpler could potentially a good thing.

For IDs though, you can just use the range function in PHP and I think it will look even better than concatenating strings. I know it is not exactly the same, but for most cases effectively it is.

It is a bit unfortunate that PHP does not have a language construct for ranges. Concatenating (or formatting) strings does not look that much better, at least to me.

And surely there are other ways we could make writing readable queries easier too. A collection of very descriptive helper functions that return arrays could for example be one and also a more extendable model for achieving that goal.

#5 @johnbillion
10 years ago

  • Keywords 2nd-opinion added
  • Version trunk deleted

While this might just be syntactical sugar, I think it has very limited use outside of date ranges. How often do you need to query for post IDs within a given range? What are the real life use cases for querying for a range of post IDs, bearing in mind that the range probably needs to be computed prior to the actual query.

Querying for posts that fall within a certain date range is, as mentioned above, much more common, but this can still be achieved with quite a concise syntax:

new WP_Query( array(
	'date_query' => array(
		array(
			'after'  => '2015-01-01',
			'before' => date( 'Y-m-d' ),
		),
	),
) );

I'd like to see some more real world examples before I'm completely convinced.

#6 @boonebgorges
10 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

I think I agree with johnbillion here. If you really need an ID range, it can be accomplished like this:

new WP_Query( array(
    'post__in' => range( $start, $end ),
) );

That's all we'd be doing internally anyway, so I don't see the benefit in adding the .. syntax, which we don't use anywhere else in WordPress.

#7 @dziudek
10 years ago

@boonebgorges , @johnbillion, @akibjorklund - ok, I understand. In fact use cases are very specific and are connected mainly with the date and ID ranges. The range function is kind of good replacement in most cases (maybe expecting ranges between big values when it will produce very big array, but it is a small part of all cases).

I thought more about this concept and now I'm thinking that this kind of syntax sugar needs to implement (especially in date ranges) additional conditions and code which could impact the WP_Query performance.

Thank you for consideration and useful discussion :)

Note: See TracTickets for help on using tickets.