i wanna create a custom search that will search posts by keyword not only in their titles and/or contents, but in post metas.

for example, from $wp_query->query_vars['s'] i got a word 'plastic' after user clicked to search.

then i have 2 path to use it: add pre_get_posts action to filter all posts that have that keyword in metas or create a new query and then filter posts in template.

i know that first case - is the right case and i should use it, but i don't really understand how find filter posts by keywords in metas.

example code:

function d_search( $query ) {
    if ($query->is_search()) {
        $query->set( 'posts_per_page', 12 );
        $query->set('meta_query', array(
                'key'    => 'something',
                'value'  => $wp_query->query_vars['s'], //plastic
                'compare' => 'LIKE'
add_action( 'pre_get_posts', 'd_search' );

my meta post with key 'something' has value 'plastic love' and as you can see my query_vars['s'] or 'plastic' is in 'plastic love' line.

why it doesnt work? just doesn't filter anything.

and in seconds case:

when i'm using my another case i have a search page http://localhost/search. i have filtered posts in global query, i have a pagination.

every button's link in pagination looks like http://localhost/search/plastic/page/2/and it doesn't work. if i open it, i just see my 404 template.

if i use http://localhost/search/plastic?paged=2 it won't work too.

how can i use first case or how can i fix second problem? (please, no plugins)

1 Answer 1


Okay. I solved it by myself. i dunno what's wrong, but it looks like using first case - just doesn't work. using second case - is a bad idea.

so i began to work with sql and posts_where commands.

first: instead of $wp_query->query_vars['s'] i started to use get_search_query()

second: looks like when sql tries to compare meta_value with value, it asks for %. yes, so in sql code you should write something like:

wp_postmeta.meta_key LIKE \'_entitle\' AND wp_postmeta.meta_value LIKE \'%' . get_search_query() . '%\'

third: because you are using wp_postmeta, you must join its posts ids with ids from wp_posts:

function dasdasd( $join, $query ) {
    global $wpdb;

    if ( is_search() ) {    
        $join = 'INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )';

    return $join;
add_filter('posts_join', 'dasdasd', 10, 2 );

and fourth: i dunno why but you must add groupby code:

add_filter( 'posts_groupby', 'adadad', 10, 2 );

function adadad( $groupby, $query ){
    $groupby = 'wp_posts.ID';

    return $groupby;

i would like to know what's wrong with fourth step and why groupby's existing is so important for search query. thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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