public void testSortNestedWithNestedFilter()

in server/src/internalClusterTest/java/org/opensearch/search/nested/SimpleNestedIT.java [1043:1437]


    public void testSortNestedWithNestedFilter() throws Exception {
        assertAcked(
            prepareCreate("test").addMapping(
                "type1",
                XContentFactory.jsonBuilder()
                    .startObject()
                    .startObject("type1")
                    .startObject("properties")
                    .startObject("grand_parent_values")
                    .field("type", "long")
                    .endObject()
                    .startObject("parent")
                    .field("type", "nested")
                    .startObject("properties")
                    .startObject("parent_values")
                    .field("type", "long")
                    .endObject()
                    .startObject("child")
                    .field("type", "nested")
                    .startObject("properties")
                    .startObject("child_values")
                    .field("type", "long")
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()
            )
        );
        ensureGreen();

        // sum: 11
        client().prepareIndex("test", "type1", "1")
            .setSource(
                jsonBuilder().startObject()
                    .field("grand_parent_values", 1L)
                    .startArray("parent")
                    .startObject()
                    .field("filter", false)
                    .field("parent_values", 1L)
                    .startArray("child")
                    .startObject()
                    .field("filter", true)
                    .field("child_values", 1L)
                    .startObject("child_obj")
                    .field("value", 1L)
                    .endObject()
                    .endObject()
                    .startObject()
                    .field("filter", false)
                    .field("child_values", 6L)
                    .endObject()
                    .endArray()
                    .endObject()
                    .startObject()
                    .field("filter", true)
                    .field("parent_values", 2L)
                    .startArray("child")
                    .startObject()
                    .field("filter", false)
                    .field("child_values", -1L)
                    .endObject()
                    .startObject()
                    .field("filter", false)
                    .field("child_values", 5L)
                    .endObject()
                    .endArray()
                    .endObject()
                    .endArray()
                    .endObject()
            )
            .get();

        // sum: 7
        client().prepareIndex("test", "type1", "2")
            .setSource(
                jsonBuilder().startObject()
                    .field("grand_parent_values", 2L)
                    .startArray("parent")
                    .startObject()
                    .field("filter", false)
                    .field("parent_values", 2L)
                    .startArray("child")
                    .startObject()
                    .field("filter", true)
                    .field("child_values", 2L)
                    .startObject("child_obj")
                    .field("value", 2L)
                    .endObject()
                    .endObject()
                    .startObject()
                    .field("filter", false)
                    .field("child_values", 4L)
                    .endObject()
                    .endArray()
                    .endObject()
                    .startObject()
                    .field("parent_values", 3L)
                    .field("filter", true)
                    .startArray("child")
                    .startObject()
                    .field("child_values", -2L)
                    .field("filter", false)
                    .endObject()
                    .startObject()
                    .field("filter", false)
                    .field("child_values", 3L)
                    .endObject()
                    .endArray()
                    .endObject()
                    .endArray()
                    .endObject()
            )
            .get();

        // sum: 2
        client().prepareIndex("test", "type1", "3")
            .setSource(
                jsonBuilder().startObject()
                    .field("grand_parent_values", 3L)
                    .startArray("parent")
                    .startObject()
                    .field("parent_values", 3L)
                    .field("filter", false)
                    .startArray("child")
                    .startObject()
                    .field("filter", true)
                    .field("child_values", 3L)
                    .startObject("child_obj")
                    .field("value", 3L)
                    .endObject()
                    .endObject()
                    .startObject()
                    .field("filter", false)
                    .field("child_values", 1L)
                    .endObject()
                    .endArray()
                    .endObject()
                    .startObject()
                    .field("parent_values", 4L)
                    .field("filter", true)
                    .startArray("child")
                    .startObject()
                    .field("filter", false)
                    .field("child_values", -3L)
                    .endObject()
                    .startObject()
                    .field("filter", false)
                    .field("child_values", 1L)
                    .endObject()
                    .endArray()
                    .endObject()
                    .endArray()
                    .endObject()
            )
            .get();
        refresh();

        // Without nested filter
        SearchResponse searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(SortBuilders.fieldSort("parent.child.child_values").setNestedPath("parent.child").order(SortOrder.ASC))
            .get();
        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("-3"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("-2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("-1"));

        // With nested filter
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .setNestedFilter(QueryBuilders.termQuery("parent.child.filter", true))
                    .order(SortOrder.ASC)
            )
            .get();
        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));

        // Nested path should be automatically detected, expect same results as above search request
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .setNestedFilter(QueryBuilders.termQuery("parent.child.filter", true))
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));

        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.parent_values")
                    .setNestedPath("parent.child")
                    .setNestedFilter(QueryBuilders.termQuery("parent.filter", false))
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));

        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedSort(
                        new NestedSortBuilder("parent").setFilter(QueryBuilders.termQuery("parent.filter", false))
                            .setNestedSort(new NestedSortBuilder("parent.child"))
                    )
                    .sortMode(SortMode.MAX)
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("4"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("6"));

        // Check if closest nested type is resolved
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_obj.value")
                    .setNestedPath("parent.child")
                    .setNestedFilter(QueryBuilders.termQuery("parent.child.filter", true))
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));

        // Sort mode: sum
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .sortMode(SortMode.SUM)
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("7"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("11"));

        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .sortMode(SortMode.SUM)
                    .order(SortOrder.DESC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("11"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("7"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("2"));

        // Sort mode: sum with filter
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .setNestedFilter(QueryBuilders.termQuery("parent.child.filter", true))
                    .sortMode(SortMode.SUM)
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));

        // Sort mode: avg
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .sortMode(SortMode.AVG)
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));

        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .sortMode(SortMode.AVG)
                    .order(SortOrder.DESC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("1"));

        // Sort mode: avg with filter
        searchResponse = client().prepareSearch()
            .setQuery(matchAllQuery())
            .addSort(
                SortBuilders.fieldSort("parent.child.child_values")
                    .setNestedPath("parent.child")
                    .setNestedFilter(QueryBuilders.termQuery("parent.child.filter", true))
                    .sortMode(SortMode.AVG)
                    .order(SortOrder.ASC)
            )
            .get();

        assertHitCount(searchResponse, 3);
        assertThat(searchResponse.getHits().getHits().length, equalTo(3));
        assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[0].getSortValues()[0].toString(), equalTo("1"));
        assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[1].getSortValues()[0].toString(), equalTo("2"));
        assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
        assertThat(searchResponse.getHits().getHits()[2].getSortValues()[0].toString(), equalTo("3"));
    }