I'm making a custom post meta search with the pre_get_posts function in my Divi child theme functions.php file. The problem is that the final query gathers not only the results for my custom post field (named 'autor') but other fields like 'post_title' and 'post_post' which I have not included.
That's the resulting query with the troublesome line highlighted in strong:
SELECT SQL_CALC_FOUND_ROWS ebj_posts.ID FROM ebj_posts INNER JOIN ebj_term_relationships ON (ebj_posts.ID = ebj_term_relationships.object_id) INNER JOIN ebj_postmeta ON ( ebj_posts.ID = ebj_postmeta.post_id ) INNER JOIN ebj_postmeta AS mt1 ON ( ebj_posts.ID = mt1.post_id ) WHERE 1=1 AND ( ebj_term_relationships.term_taxonomy_id IN (456) ) AND (((ebj_posts.post_title LIKE '%Abulafia%') OR (ebj_posts.post_content LIKE '%Abulafia%'))) AND ( ebj_postmeta.meta_key = 'autor' AND ( ( mt1.meta_key = 'autor' AND CAST(mt1.meta_value AS CHAR) LIKE '%Abulafia%' ) ) ) AND ebj_posts.post_type IN ('post', 'page', 'attachment', 'project', 'ref_bib') AND ((ebj_posts.post_status = 'publish')) GROUP BY ebj_posts.ID ORDER BY ebj_postmeta.meta_value ASC LIMIT 0, 30"
As you can see the word 'Abulafia' is searched in the post_title and post_content fields, which is not intended.
This line in bold with the AND arguments come from WP > wp-includes > query line 2196:
$search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like );
because when I comment these line in the wordpress core code the problem vanish.
That's my code in functions.php:
function filtra_inici( $query ){
global $wp;
if ( ( is_archive() ) && $query->is_main_query() && !is_admin() ) {
if ($query->is_search && isset($_GET['search-type']) && $_GET['search-type'] == 'autor') {
$query->set( 'post_type', 'ref_bib');
$query->set( 'post_status', 'publish');
$query->set( 'orderby', 'meta_value');
$query->set( 'meta_key', 'autor' );
$query->set( 'order', 'ASC' );
$meta_query = array('relation' => 'AND');
array_push( $meta_query, array(
'key' => 'autor',
'value' => $query->query_vars['s'],
'compare' => 'LIKE'
));
$query->set( 'meta_query', $meta_query);
}
}// end is_archive
}
Thanks!
WP_Query
is to retrieve posts, and that's exactly what it's doing, and that's the job of the main query. What you're seeing is expected behaviourpre_get_posts
filter, but lets say that you did indeed make WP_Query retrieve only the post meta, how would you pull that data out? WP_Query deals with WP_Post objects, that information is necessary. Even if you managed it, it would screw up any other code running on that page, and have unpredictable results. What you're trying to do is not the way things are meant to work, why is it you need the main query to fetch the meta for the posts and only the meta?