5

How do I query by meta_value or title?

If I set meta_values,

$args['meta_query'] = array(
   'relation' => 'OR',
    array(
        'key' => 'model_name',
        'value' => $thesearch,
        'compare' => 'like'
    )
);

they automatically get added as AND.

This search would be:

 WHERE title = 'Search' AND (model_name = 'Search' OR ...)

I need

WHERE title = 'Search' OR (model_name = 'Search' OR ...)
  • I tried adding $args['relation'] = 'OR'; But, it is not recognized. Seems like I missing how to control conditional logic through args. – Bryan Feb 18 '15 at 1:04
15

Note that the relation part in the meta_query argument, is only used to define the relation between the sub meta queries.

You can try this setup:

$args = [ 
    '_meta_or_title' => $thesearch,   // Our new custom argument!
    'meta_query'    => [
        [
            'key'     => 'model_name',
            'value'   => $thesearch,
            'compare' => 'like'
        ]
    ],
];

where we have introduced a custom argument _meta_or_title to activate the meta OR title query.

This is supported by the following plugin:

<?php
/**
 *  Plugin Name:   Meta OR Title query in WP_Query
 *  Description:   Activated through the '_meta_or_title' argument of WP_Query 
 *  Plugin URI:    http://wordpress.stackexchange.com/a/178492/26350
 *  Plugin Author: Birgir Erlendsson (birgire)
 *  Version:       0.0.1
 */

add_action( 'pre_get_posts', function( $q )
{
    if( $title = $q->get( '_meta_or_title' ) )
    {
        add_filter( 'get_meta_sql', function( $sql ) use ( $title )
        {
            global $wpdb;

            // Only run once:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // Modify WHERE part:
            $sql['where'] = sprintf(
                " AND ( %s OR %s ) ",
                $wpdb->prepare( "{$wpdb->posts}.post_title = '%s'", $title ),
                mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
            );
            return $sql;
        });
    }
});
  • Wow. Awesome answer! This should be in the core. – Bryan Feb 18 '15 at 20:06
  • The answer got me 1/2 way there. wordpress.stackexchange.com/questions/178574/… Any idea on this next one? – Bryan Feb 18 '15 at 20:16
  • I have used this answer to create a query for one specific meta value on the edit.php page for a custom post type. I don't query the title at all, because my custom post type has no title. Therefore, I replaced " AND ( %s OR %s ) " by " OR ( %s ) " in the sql query and got rid of the line $wpdb->prepare( "{$wpdb->posts}.post_title = '%s'", $title ), altogether. Is this a valid approach? – BdN3504 May 17 '15 at 10:30
  • 3
    Great trick. If you want a substring search for the title, replace post_title = '%s' with post_title like '%%%s%%'. – jarnoan Sep 30 '15 at 10:11
  • 1
    @jeff I once wrote a plugin to combine queries: github.com/birgire/wp-combine-queries. Also here I played with search (title, excerpt, content ) or tax query. Here I found another similar answer that I experimented with. We can also write two separate WP_Query, then collect and combine the resulting post ids into a third WP_Query (if needed and if PHP ordering is not enough) via post__in input parameter. – birgire Oct 13 '18 at 17:39

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.