SearchWP

This Documentation is for SearchWP Version 3

Advanced Filtration of Results Based on Post Meta (Custom Fields)

More advanced search implementations usually focus on some sort of filtration. Out of the gate something like FacetWP is likely the best solution, but you may find yourself in a unique situation needing to limit the potential search results pool.

The easiest way to limit the main search results pool when a search is taking place is to take advantage of the searchwp_include and searchwp_exclude hooks. Both filters allow you to limit potential search results by either forcefully including or forcefully excluding post IDs. One (or both) of these filters will meet the majority of needs, but those filters aren’t completely scalable. You may need to limit the results pool to thousands of entries because there are tens of thousands of entries to search. Using these filters with such high volume may cause you to exceed the limits of MySQL on your server, resulting in errors like “MySQL has gone away“.

To resolve this issue, you can implement something like the following, and offload your usage of searchwp_include or searchwp_exclude to a meta_query that is directly integrated with the main search query SearchWP performs. Usage will be familiar if you’ve performed a meta_query via WP_Query before.

To take advantage of this feature, use the following as a guide. This snippet allows you to integrate your own meta_query directly with SearchWP’s main search, effectively allowing you to limit the search results pool based on your post_meta requirements at runtime.

<?php
/*
* In this particular implementation I am looking to limit the search results pool based on an
* additional form field I have set up that allows people to search entries based on the number
* of bedrooms, which is stored as post_meta with a meta_key of listing_bedrooms
*/
function my_searchwp_query_join( $sql, $engine ) {
global $wpdb;
$meta_query_args = array(
array(
'key' => 'listing_bedrooms',
'value' => isset( $_GET["beds"] ) ? absint( $_GET["beds"] ) : 0,
'compare' => '>=',
"type" => "NUMERIC",
)
);
$meta_query = new WP_Meta_Query( $meta_query_args );
$mq_sql = $meta_query->get_sql(
'post',
$wpdb->posts,
'ID',
null
);
return $sql . $mq_sql['join'];
}
add_filter( 'searchwp_query_main_join', 'my_searchwp_query_join', 10, 2 );
function my_searchwp_query_conditions( $sql, $engine ) {
global $wpdb;
$meta_query_args = array(
array(
'key' => 'listing_bedrooms',
'value' => isset( $_GET["beds"] ) ? absint( $_GET["beds"] ) : 0,
'compare' => '>=',
"type" => "NUMERIC",
)
);
$meta_query = new WP_Meta_Query( $meta_query_args );
$mq_sql = $meta_query->get_sql(
'post',
$wpdb->posts,
'ID',
null
);
return $sql . $mq_sql['where'];
}
add_filter( 'searchwp_where', 'my_searchwp_query_conditions', 10, 2 );
view raw gistfile1.php hosted with ❤ by GitHub

As called out in the comments, this particular implementation is based on a custom search form that has been set up that allows the visitor to populate a second field with a name of beds which limits the search results pool to entries with at least that number of bedrooms (which are stored as post_meta with a meta_key of listing_bedrooms).

Naturally, this snippet would need to be customized to your implementation, but as you can see it uses the same meta_query you would use when fetching entries via standard WP_Query.