You could try modifying the tax query to use the relation
parameter and add a second clause that matches any post that does not have the matched string
value in the meta array.
function group_matched_posts_at_top( $query ) {
// Check if this is the main query and not in the admin area
if( !$query->is_main_query() || is_admin() )
return;
// Define the tax query with two clauses (matched and not matched)
$taxquery = array(
'relation' => 'OR', // Set the relation to OR to include posts that match either clause
array(
'taxonomy' => 'mymeta',
'field' => 'slug',
'terms' => 'matchedstring',
'compare'=> 'IN'
),
array(
'taxonomy' => 'mymeta',
'field' => 'slug',
'terms' => 'matchedstring',
'compare'=> 'NOT IN'
)
);
// Set the tax query and meta key parameters for the query
$query->set( 'tax_query', $taxquery );
$query->set( 'meta_key', 'mymeta' );
// Set the orderby parameter to sort by the value of the "mymeta" field in descending order (so that matched posts appear first), and then by date in descending order (so that the most recent posts appear first within each group).
$query->set( 'orderby', array( 'meta_value' => 'DESC', 'date' => 'DESC' ) );
}
add_action( 'pre_get_posts', 'group_matched_posts_at_top' );