Filter keywords from search query

If I understand you correctly you’re not looking for the wp_search_stopwords filter type of solution.

So here’s a modification of the great answer by @kaiser that you referred to:

/**
 * Exclude array of words from all search queries in the front-end
 *
 * Modification of http://wordpress.stackexchange.com/a/41100/26350 by @kaiser
 */

add_filter( 'posts_search', function( $search, $q )
{
    // Target all search queries in the front-end:
    if( is_admin() || ! $q->is_search() ) return $search;

    global $wpdb;

    $exclude_words = [ 'foo', 'bar' ]; // <-- Modify this to your needs!

    $sql = " AND {$wpdb->posts}.post_title   NOT LIKE '%%%s%%' 
             AND {$wpdb->posts}.post_content NOT LIKE '%%%s%%' ";

    foreach( (array) $exclude_words as $word )
        $search .= $wpdb->prepare(
           $sql,
           $wpdb->esc_like( $word ),
           $wpdb->esc_like( $word )
        );

    return $search;
}, 10, 2 );

where you have to modify the $exclude_words to your needs. Here we target all search queries in the front-end.

Notice the '%%%s%%' part. It will be transformed into '%someword%' in the generated SQL query. It’s also tempting to use %1$s for repeating use of the same string, but it’s not supported by $wpdb->prepare(). If we would use sprintf instead, we have to make sure it’s not translated into the $s variable within a string with double quotes: "$s".

If we only want to modify the main search query, we could use:

    if( is_admin() || ! $q->is_main_query() || ! $q->is_search() ) return $search;

instead of this check:

    if( is_admin() || ! $q->is_search() ) return $search;

Update:

We can now search with foo -bar to exclude bar from the foo search.

Then one could play with something like:

add_action( 'pre_get_posts', function( \WP_Query $q )
{
    if ( ! is_admin() && $q->is_main_query() && $q->is_search() )
        $q->set( 's', $q->get( 's' ) . ' -bar' );

} );

Note that the search exclusion prefix can be changed with the wp_query_search_exclusion_prefix filter.

Leave a Comment