Replacing search results with custom external query

You can’t return a query object from a pre_get_posts action. In fact, it shouldn’t return anything, the query object is passed by reference.

Your second attempt is close, you can unset the s query var so WordPress doesn’t try to search on that term. Of course, now s has no value, so any functions that try to output the search term will just get an empty string.

add_action('pre_get_posts', 'my_search_query');
function my_search_query($query) {
    if($query->is_search() && $query->is_main_query() && get_query_var('s', false)) {
        // get your $ids, then
        unset( $query->query_vars['s'] );
        $query->set( 'post__in', $ids );
    }
}