Changing the ORDER BY in WordPress default search function

If I were you, I would likely use the posts_search_orderby hook to change the search ORDER BY clause, because that way, the sorting would work with pagination.

So for example in your case, you would want to sort by the post type like so: (well, if the “product posts” is of a different post type?)

// In functions.php:

add_filter( 'posts_search_orderby', 'my_posts_search_orderby', 10, 2 );
function my_posts_search_orderby( $orderby, $query ) {
    if ( $query->is_main_query() && is_search() ) {
        global $wpdb;
        $orderby = "{$wpdb->posts}.post_type";
    }

    return $orderby;
}

But if you just want an on-same-page sorting, then you can just go with the second option, like so which uses the native usort() and strcmp() functions in PHP:

// In functions.php:

add_filter( 'the_posts', 'my_the_posts', 10, 2 );
function my_the_posts( $posts, $query ) {
    if ( $query->is_main_query() && is_search() ) {
        usort( $posts, function ( $a, $b ) {
            return strcmp( $a->post_type, $b->post_type ); // A-Z (ASCending)
//          return strcmp( $b->post_type, $a->post_type ); // Z-A (DESCending)
        } );
    }

    return $posts;
}

That, however, uses the the_posts hook instead of modifying the search results template, but the point is, do the sorting manually after the posts have been retrieved. 🙂

And if you actually meant to sort by the post categories, then this may not be a solution for you, but the same concept (or hooks) can be used.