0

I need to create a very complex post query, but I don't know if such a query can exist, or if I have to write PHP code to combine the results of two different queries...

Let me please describe the situation first, and then write what I've done so far.

So, I need to return results from a CPT. The CPT has its own taxonomy, where I've inserted the necessary terms. The terms have to do with different genre of the CPT itself. There is a specific term, that I don't want results from, there is the majority of the terms that I want to retrieve the results of a given date, and there are 3 specific terms, that I want results from the last 5 days of that same given date.

If that was the case, I'd simply write two different queries, and merge the results in a single array for display.

The problem is that ALL returned posts (the ones of that given date, and those from the last 5 days) need to be sorted by a custom field. In my individual queries I took that sorting into consideration using the appropriate orderby arguements, but when combined, the total sorting is gone, because I get the results of the first query sorted alone, and then the results of the second query sorted alone; where I need them to be sorted combined. So let me write the code of the queries...

This is the first excluding the 4 specific terms:

$args1 = array(
    'post_type' => 'frontpage',
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
    'meta_key' => 'frontpage_order',
    'posts_per_page' => -1,
    'date_query' => array(
        array(
            'year' => date('Y', $date),
            'month' => date('m', $date),
            'day' => date('d', $date),
        ),
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'newspaper_genre',
            'field' => 'term_id',
            'terms' => array(
                7670,
                7674,
                7684,
                7686,
            ),
            'operator' => 'NOT IN',
        ),
    ),
);

And the second that includes only the 3 specific terms:

$args2 = array(
    'post_type' => 'frontpage',
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
    'meta_key' => 'frontpage_order',
    'posts_per_page' => -1,
    'date_query' => array(
        array(
            'after' => array(
                'year' => date('Y', $date_minus_five),
                'month' => date('m', $date_minus_five),
                'day' => date('d', $date_minus_five),
            ),
            'before' => array(
                'year' => date('Y', $date),
                'month' => date('m', $date),
                'day' => date('d', $date),
            ),
            'inclusive' => true,
        ),
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'newspaper_genre',
            'field' => 'term_id',
            'terms' => array(
                7674,
                7684,
                7686,
            ),
            'operator' => 'IN',
        ),
    ),
);

So, the question is, am I missing a query setup where I can somehow combine specific date_query params with speecific tax_query params, and also other date_query params with other tax_query params and all these in a single query?

Or do I have to merge, the two retrieved resultsets, and then redo the sorting programmatically?

TIA

3
  • did you try nesting your two tax queries exactly how you nested your date_query? It should work fine.
    – rudtek
    Mar 17 at 5:22
  • It shouldn't, and wouldn't, work because each different term corresponds to different days. So it's not a matter of nesting 2-3 different tax_query setups because in that case all of them would share the same period of time (a.k.a date_query). The approach is different, and for the sake of completeness I'll share it as an answer later today!
    – Peter K.
    Mar 17 at 17:15
  • good luck to you Peter.
    – rudtek
    Mar 19 at 4:32
1

I got inspired in solving my problem by this thread!

The idea is to create individual queries (unordered to save time, as sorting is not needed at this stage) to get the post IDs that meet your criteria; then take those IDs and run a final query with the IDs as the criteria to get the full posts (ordered and everything at this stage). Such a code would look like this:

$ids1 = get_posts(array(
    'fields' => 'ids',
    'post_type' => 'frontpage',
    'posts_per_page' => -1,
    'date_query' => array(
        array(
            'year' => date('Y', $date),
            'month' => date('m', $date),
            'day' => date('d', $date),
        ),
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'newspaper_genre',
            'field' => 'term_id',
            'terms' => array(
                7670,
                7674,
                7682,
                7684,
                7686,
                8099,
                8101,
            ),
            'operator' => 'NOT IN',
        ),
    ),
));

$ids2 = get_posts(array(
    'fields' => 'ids',
    'post_type' => 'frontpage',
    'posts_per_page' => -1,
    'date_query' => array(
        array(
            'year' => date('Y', $date),
            'month' => date('m', $date),
        ),
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'newspaper_genre',
            'field' => 'term_id',
            'terms' => array(
                7682,
                8099,
                8101,
            ),
            'operator' => 'IN',
        ),
    ),
));

$ids3 = get_posts(array(
    'fields' => 'ids',
    'post_type' => 'frontpage',
    'posts_per_page' => -1,
    'date_query' => array(
        array(
            'after' => array(
                'year' => date('Y', $date_minus_five),
                'month' => date('m', $date_minus_five),
                'day' => date('d', $date_minus_five),
            ),
            'before' => array(
                'year' => date('Y', $date),
                'month' => date('m', $date),
                'day' => date('d', $date),
            ),
            'inclusive' => true,
        ),
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'newspaper_genre',
            'field' => 'term_id',
            'terms' => array(
                7674,
                7684,
                7686,
            ),
            'operator' => 'IN',
        ),
    ),
));

$query = get_posts(array(
    'include' => array_merge($ids1, $ids2, $ids3),
    'post_type' => 'frontpage',
    'orderby' => array(
        'meta_value_num' => 'ASC',
        'date' => 'ASC',
    ),
    'meta_key' => 'frontpage_order',
)); 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.