Add these filters to your functions.php
file
/**
* Join posts and postmeta tables
*
* @link https://developer.wordpress.org/reference/hooks/posts_join/
*/
add_filter( 'posts_join', function( string $sql, WP_Query $query ) {
global $wpdb;
if ( !is_admin() && $query->get( 'search_meta' ) ) {
$sql .= ' LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
}
return $sql;
}, 10, 2 );
/**
* Modify the search query with posts_where
*
* @link https://developer.wordpress.org/reference/hooks/posts_where/
*/
add_filter( 'posts_where', function( string $sql, WP_Query $query ) {
global $wpdb;
if ( !is_admin() && $query->get( 'search_meta' ) ) {
$field_query = '';
if ( is_string( $query->get( 'search_meta' ) ) ) {
$field_name = $query->get( 'search_meta' );
$field_query = "AND {$wpdb->postmeta}.meta_key = '{$field_name}'";
}
$sql = preg_replace( '/\(\s*' . $wpdb->posts . '.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/', '(' . $wpdb->posts . '.post_title LIKE $1) OR (' . $wpdb->postmeta . '.meta_value LIKE $1' . $field_query . ')', $sql );
}
return $sql;
}, 10, 2 );
/**
* Prevent duplicates
*
* @link https://developer.wordpress.org/reference/hooks/posts_distinct/
*/
add_filter( 'posts_distinct', function( string $sql, WP_Query $query ) {
if ( !is_admin() && $query->get( 'search_meta' ) ) {
return 'DISTINCT';
}
return $sql;
}, 10, 2 );
And then you just need to add the search_meta
argument in your request. To search all meta values use 'search_meta' => true
…
add_action( 'wp_ajax_data_fetch', 'data_fetch' );
add_action( 'wp_ajax_nopriv_data_fetch', 'data_fetch' );
function data_fetch() {
$recipes = new WP_Query( [
'post_type' => 'project5',
'orderby' => 'rand',
'post_status' => 'publish',
's' => esc_attr( $_POST['keyword'] ),
'search_meta' => true
] );
}
Or to search a specific field value use 'search_meta' => 'MY_FIELD_NAME'
…
add_action( 'wp_ajax_data_fetch', 'data_fetch' );
add_action( 'wp_ajax_nopriv_data_fetch', 'data_fetch' );
function data_fetch() {
$recipes = new WP_Query( [
'post_type' => 'project5',
'orderby' => 'rand',
'post_status' => 'publish',
's' => esc_attr( $_POST['keyword'] ),
'search_meta' => 'keyword' // Name of custom meta_key
] );
}
This hasn’t been fully tested so please keep that in mind.
EDIT
A “less overkill” approach is to use the meta parameters in WP_Query (docs here). For example…
add_action( 'wp_ajax_data_fetch', 'data_fetch' );
add_action( 'wp_ajax_nopriv_data_fetch', 'data_fetch' );
function data_fetch() {
$input = esc_attr( $_POST[ 'keyword' ] );
$recipes = new WP_Query( [
'post_type' => 'project5',
'orderby' => 'rand',
'post_status' => 'publish',
's' => $input,
'meta_key' => 'MY_CUSTOM_FIELD_DATABSE_KEY',
'meta_value' => $input,
'meta_compare' => 'LIKE'
] );
}