public void testCrossFieldMode()

in server/src/internalClusterTest/java/org/opensearch/search/query/MultiMatchQueryIT.java [703:999]


    public void testCrossFieldMode() throws ExecutionException, InterruptedException {
        SearchResponse searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america", "full_name", "first_name", "last_name").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).operator(Operator.OR)
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("marvel hero captain america", "full_name", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).operator(Operator.OR)
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theother"));
        assertSecondHit(searchResponse, hasId("theone"));
        assertThat(searchResponse.getHits().getHits()[0].getScore(), greaterThan(searchResponse.getHits().getHits()[1].getScore()));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("marvel hero", "full_name", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).operator(Operator.OR)
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theother"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america", "full_name", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america 15", "full_name", "first_name", "last_name", "category", "skill").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).analyzer("category").lenient(true).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america 15", "full_name", "first_name", "last_name", "category", "skill", "int-field").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).analyzer("category").lenient(true).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america 15", "skill", "full_name", "first_name", "last_name", "category", "int-field").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).analyzer("category").lenient(true).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america 15", "first_name", "last_name", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                        .lenient(true)
                        .analyzer("category")
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(randomizeType(multiMatchQuery("15", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).analyzer("category")))
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(randomizeType(multiMatchQuery("25 15", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).analyzer("category")))
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("25 15", "int-field", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).analyzer("category")
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("25 15", "first_name", "int-field", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                        .analyzer("category")
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("25 15", "int-field", "skill", "first_name").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                        .analyzer("category")
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("25 15", "int-field", "first_name", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                        .analyzer("category")
                )
            )
            .get();
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).cutoffFrequency(0.1f).analyzer("category").operator(Operator.OR)
                )
            )
            .get();
        assertFirstHit(searchResponse, anyOf(hasId("theother"), hasId("theone")));
        long numResults = searchResponse.getHits().getTotalHits().value;

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).analyzer("category").operator(Operator.OR)
                )
            )
            .get();
        assertThat(numResults, lessThan(searchResponse.getHits().getTotalHits().value));
        assertFirstHit(searchResponse, hasId("theone"));

        // test group based on analyzer -- all fields are grouped into a cross field search
        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).analyzer("category").operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));
        // counter example
        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
                        randomBoolean() ? MultiMatchQueryBuilder.Type.CROSS_FIELDS : MultiMatchQueryBuilder.DEFAULT_TYPE
                    ).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 0L);

        // counter example
        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
                        randomBoolean() ? MultiMatchQueryBuilder.Type.CROSS_FIELDS : MultiMatchQueryBuilder.DEFAULT_TYPE
                    ).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 0L);

        // test if boosts work
        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("the ultimate", "full_name", "first_name", "category").field("last_name", 10)
                        .type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                        .operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 2L);
        assertFirstHit(searchResponse, hasId("ultimate1"));   // has ultimate in the last_name and that is boosted
        assertSecondHit(searchResponse, hasId("ultimate2"));
        assertThat(searchResponse.getHits().getHits()[0].getScore(), greaterThan(searchResponse.getHits().getHits()[1].getScore()));

        // since we try to treat the matching fields as one field scores are very similar but we have a small bias towards the
        // more frequent field that acts as a tie-breaker internally
        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("the ultimate", "full_name", "first_name", "last_name", "category").type(
                        MultiMatchQueryBuilder.Type.CROSS_FIELDS
                    ).operator(Operator.AND)
                )
            )
            .get();
        assertHitCount(searchResponse, 2L);
        assertFirstHit(searchResponse, hasId("ultimate2"));
        assertSecondHit(searchResponse, hasId("ultimate1"));
        assertThat(searchResponse.getHits().getHits()[0].getScore(), greaterThan(searchResponse.getHits().getHits()[1].getScore()));

        // Test group based on numeric fields
        searchResponse = client().prepareSearch("test")
            .setQuery(randomizeType(multiMatchQuery("15", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)))
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(randomizeType(multiMatchQuery("15", "skill", "first_name").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)))
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        // Two numeric fields together caused trouble at one point!
        searchResponse = client().prepareSearch("test")
            .setQuery(randomizeType(multiMatchQuery("15", "int-field", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)))
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(multiMatchQuery("15", "int-field", "first_name", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS))
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("theone"));

        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("alpha 15", "first_name", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).lenient(true)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("ultimate1"));
        /*
         * Doesn't find theone because "alpha 15" isn't a number and we don't
         * break on spaces.
         */
        assertHitCount(searchResponse, 1);

        // Lenient wasn't always properly lenient with two numeric fields
        searchResponse = client().prepareSearch("test")
            .setQuery(
                randomizeType(
                    multiMatchQuery("alpha 15", "int-field", "first_name", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
                        .lenient(true)
                )
            )
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("ultimate1"));

        // Check that cross fields works with date fields
        searchResponse = client().prepareSearch("test")
            .setQuery(randomizeType(multiMatchQuery("now", "f*", "date").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)).lenient(true))
            .get();
        assertHitCount(searchResponse, 1L);
        assertFirstHit(searchResponse, hasId("nowHero"));
    }