Support

Account

Home Forums General Issues meta_query not working and stopping all results

Solved

meta_query not working and stopping all results

  • I have been trying everything I can think of but there’s something about trying to include custom fields in a meta_query I am just not getting.

    Any help appreciated!

    
    
    add_filter('pre_get_posts', __NAMESPACE__ . '\\search_custom_fields');
    // add_action('pre_get_posts', __NAMESPACE__ . '\\search_custom_fields');
    
    function search_custom_fields($query)
    {
        if ($query->is_search && $query->is_main_query()) {
            echo "search_custom_fields:   " . $query->is_main_query() . " " . $query->is_search . "\n";
            echo "query->post_type: " . get_query_var('post_type') . "\n";
            echo "Setting meta_query in search_custom_fields. " . "\n\n\n";
    
            // i want the search to include custom fields as well as continue to include the title and post content. So i want to return ANY matches from any of the fields
            
            $search_word = get_query_var('s'); // 'test' for post title and content.
            $query->set('post_type', 'location'); // search is only for post type 'locations'
            $query->set('orderby', 'date');
            $query->set('order', 'DSC');
    
            // this taxonomy test works and returns results with title LIKE 'test' with this term
            $tax = array(
                array(
                    'taxonomy' => 'location_facilities',
                    'field'    => 'slug',
                    'terms'    => 'inside-m25',
                ));
            $query->set('tax_query', $tax);
    
            // acf field is called 'loc_refid'
            // this stops all results
            $meta_query1 =
                [
                [
                    'key'     => 'loc_refid',
                    'value'   => "%" . $search_word . "%",
                    'compare' => 'LIKE',
                ],
            ];
            // returns general matches but nothing for the loc_refid field
            $meta_query2 = [
                'key'     => 'loc_refid',
                'value'   => "%" . $search_word . "%",
                'compare' => 'LIKE',
            ];
    
            // // this stops all results
            $meta_query3 = [
                'relation' => 'OR',
                [
                    'key'     => 'loc_refid',
                    'value'   => $search_word,
                    'compare' => 'LIKE',
                ],
            ];
    
            $meta_query4 = array(
                'relation' => 'OR',
                array(
                    'key'     => 'loc_refid',
                    'value'   => $search_word,
                    'compare' => 'LIKE',
                ),
                array(
                    'key'     => 'location_postcode_preview',
                    'value'   => $search_word,
                    'compare' =>'LIKE'
                ),
            );
    
            $query->set('meta_query', $meta_query4);
            print_r($query);
    
        }
    
        return $query; 
        // if useing add_action no need to return
    }
    

    print_r($query);

    WP_Query Object
    (
        [query] => Array
            (
                [s] => test
            )
    
        [query_vars] => Array
            (
        ...
            [tax_query] => Array
                    (
                        [0] => Array
                            (
                                [taxonomy] => location_facilities
                                [field] => slug
                                [terms] => inside-m25
                            )
    
                    )
    
             [meta_query] => Array
                    (
                        [relation] => OR
                        [0] => Array
                            (
                                [key] => loc_refid
                                [value] => test
                                [compare] => LIKE
                            )
    
                        [1] => Array
                            (
                                [key] => location_postcode_preview
                                [value] => test
                                [compare] => LIKE
                            )
    
                    )
    
            )
    
        [tax_query] => WP_Tax_Query Object
            (
                [queries] => Array
                    (
                    )
    
                [relation] => AND
                [table_aliases:protected] => Array
                    (
                    )
    
                [queried_terms] => Array
                    (
                    )
    
                [primary_table] => 
                [primary_id_column] => 
            )
    
        [meta_query] => 
        [date_query] => 
        [post_count] => 0
    ...
  • The problem with altering the search query is that the search word would need to be in:

    (title OR content) AND $custom_field

    and this is why no results are returned, because the search terms are likely not in both places.

    Here is an explanation on how to do what you’re trying to do https://adambalee.com/search-wordpress-by-custom-fields-without-a-plugin/

  • thanks I’ve seen that solution but its 5 years old now.

    Is it possible to re-include (title OR content) with $query.set() somehow?

    And seems odd that the taxonomy works. And tax_query is in query_vars[] & query[] but meta_query is missing from query[]?

    query[][tax_query] => WP_Tax_Query Object
            (
                [queries] => Array
        ....
    query[][meta_query] => 
  • Nothing has changed about the way search queries work in WP in 5 years and this is not likely to ever change.

    The tax query works the same way, try searching for a term you know does not exist on a post that is assigned to a specific term.

  • Thanks for the input John.

    A search for a string that does not exist does not return results – as expected. Or am I missing something here?

    The term can be in the title OR content OR any custom field defined in meta_query.

    Are you saying WordPress forces an AND to it.

    WordPress forces
    post_title, post_content AND (custom_field_1 OR custom_field_2 …) ?

    But I want
    post_title, post_content OR (custom_field_1 OR custom_field_2 …) ?

    thanks, D.

  • Exactly, WP forces this

    post_title, post_content AND (custom_field_1 OR custom_field_2 …) ?

    You must add code to alter the WHERE portion of the query as in the link provided to get this

    post_title, post_content OR (custom_field_1 OR custom_field_2 …) ?

  • Finally got this working and stable. A mixture of sources.
    Had a few issues with the fact I was creating an ajax search for a front end form.

    And them wanted to search more private fields in the admin using is_search && is_admin. The below is just for the ajax search. Set $GLOBALS[‘fd_search_term’] when the form data is posted.

    
    function cf_search_join($join)
    {
        global $wpdb;
    
        if (!is_search()) {
            $join .= ' LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
        }
    
        return $join;
    }
    add_filter('posts_join', __NAMESPACE__ . '\\cf_search_join');
     
    function cf_search_where($where)
    {
        global $wpdb;
    
        // do not use !is_admin() as ajax returns this as true for ajax you can use :   !isset($GLOBALS['current_screen']) && !is_customize_preview() 
        if (!is_search() && $GLOBALS['fd_search_term']) {
    
            $s = $GLOBALS['fd_search_term'];
            // i have global array for each field to include.
            // To include all fields remove ' " . $wpdb->postmeta . ".meta_key IN ($imploded_fields) AND '
            $imploded_fields = implode(',', $GLOBALS['added_meta_field_to_search_query']);
    
            $where = preg_replace("/\(\s*" . $wpdb->posts . ".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
                "(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_key IN ($imploded_fields) AND " . $wpdb->postmeta . ".meta_value LIKE $1)  ", $where);
        }
    
        return $where;
    }
    add_filter('posts_where', __NAMESPACE__ . '\\cf_search_where');
    
    function cf_search_distinct($where)
    {
        global $wpdb;
    
        if (!is_search()) {
            return "DISTINCT";
        }
    
        return $where;
    }
    add_filter('posts_distinct', __NAMESPACE__ . '\\cf_search_distinct');
    
Viewing 7 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.