Wordpress query with sub relations

2019-03-05 23:37发布

问题:

Is there a way to have a meta_query with sub relations? I don't want one relation to apply to all of the query's arrays.

I tried this, but to no avail:

'meta_query' => array(
    array(
        'key' => 'event_type',
        'value' => 'session',
        'compare' => 'LIKE'
    ),
    array(
        'relation' => 'OR',
        array(
            'key' => 'event_video',
            'value' => '0',
            'compare' => '>'
        ),
        array(
            'key' => 'event_summary',
            'value' => '',
            'compare' => '!='
        )
    ),
    array(
        'key' => 'event_date_single',
        'value' => '',
        'compare' => 'LIKE'
    ),
    array(
        'key' => 'event_start_time',
        'value' => '',
        'compare' => 'LIKE'
    )
)

So 'relation' => 'OR' should only apply between event_video and event_summary. Everything else is independent of one another. Is this possible somehow?

Thanks

回答1:

It looks like this could be a meta_query limitation. WP Codex shows that you can use relations for meta queries, but as far as I see the limitation is that you can only use one kind of relation for the whole meta_query.

This means you can have a full OR or a full AND (default) relation between meta_query parameters, but you can never have them both combined, which is just what you want.

As I was not glad when I faced it at WP Codex, I went deeper in the matter by manually searching the code. So I found out that WP_Query calls WP_Meta_Query to parse meta_query parameters. This is WP_Meta_Query's class constructor (you can find it in wp-includes/meta.php at line 643 in WP 3.6):

/**
 * Constructor
 *
 * @param array $meta_query (optional) A meta query
 */
function __construct( $meta_query = false ) {
    if ( !$meta_query )
        return;

    if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) {
        $this->relation = 'OR';
    } else {
        $this->relation = 'AND';
    }

    $this->queries = array();

    foreach ( $meta_query as $key => $query ) {
        if ( ! is_array( $query ) )
            continue;

        $this->queries[] = $query;
    }
}

Long story short, the second if shows that this class will work only either with a OR or AND relation, but never with both of them combined.

So, unfortunately, it seems that it's not possible to achieve what you are trying to do (at least until WP 3.6). I guess your best shot is to split the main query, first doing specific Meta Queries and then applying their results(returned metas) to your main query.

I know that this is not a solution but an answer. Nevertheless, I hope this may help you to find a solution for this matter.



标签: wordpress