Opposite Index for taxonomy, for a “not in” facet

<?php
/**
 * An opposite/negative/excluding index for taxonomies
 * For example if recipes are tagged "gluten" to indicate an allergy, this will index everything
 * not tagged gluten so that selecting a facet choice gluten allergen would display all recipes without gluten
 * Only for taxonomies
 * Ignores hierarchy, ignores modifier settings in facet
 * Re-index after adding this code
 */
add_filter( 'facetwp_indexer_post_facet', function( $bypass, $params ) {
    if ( 'my_categories' == $params['facet']['name'] ) { // 'my_categories' change to name of facet

        $post_id = $params['defaults']['post_id'];

        /** checks post type, otherwise post types that don't have this taxonomy would get indexed for all terms */
        if ( 'product' !== get_post_type( $post_id ) ) { // change 'product' to your post type
            return true; // skip indexes this facet
        }

        /** this assumes the datasource is a taxonomy, it can just be hardcoded instead of checking the facet setting and extracting the name */
        $taxonomy = substr( $params['defaults']['facet_source'], 4 ); 

        $terms = get_terms( [ 'taxonomy' => $taxonomy, 'hide_empty' => false ] );

        $post_terms = get_the_terms( $post_id, $taxonomy );
        $post_terms = wp_list_pluck( $post_terms, 'term_id' ); // gets all term ids for this post

        foreach ( $terms as $term ) {
            if ( !in_array( $term->term_id, $post_terms ) ) { // only index terms not set for this post.
                $row = $params['defaults'];
                $row['facet_value'] = $term->slug;
                /** since this is the opposite, for example, you might change the name "Gluten" to "Gluten Free" like this:
                 * $row['facet_display_value'] = $term->name . " Free";
                 */
                $row['facet_display_value'] = $term->name;
                $row['term_id'] = $term->term_id;
                FWP()->indexer->index_row( $row );
            }
        }

        $bypass = true; // skip normal indexing
    }
    return $bypass;
}, 10, 2 );