@Override
    public Set<IndexRange> indexRangesForStreamsInTimeRange(Set<String> streamIds, TimeRange timeRange) {
        return indexLookup.indexRangesForStreamsInTimeRange(streamIds, timeRange);
    }
@Test
    public void testExplain() {
        when(indexLookup.indexRangesForStreamsInTimeRange(anySet(), any())).thenAnswer(a -> {
            if (a.getArgument(1, TimeRange.class).getFrom().getYear() < 2024) {
                return Set.of(
                        MongoIndexRange.create("graylog_0", nowUTC(), nowUTC(), nowUTC(), 0),
                        MongoIndexRange.create("graylog_1", nowUTC(), nowUTC(), nowUTC(), 0),
                        MongoIndexRange.create("graylog_warm_2", nowUTC(), nowUTC(), nowUTC(), 0)
                );
            }
            return Set.of(MongoIndexRange.create("graylog_0", nowUTC(), nowUTC(), nowUTC(), 0));
        });

        final Query query = Query.builder()
                .id("query1")
                .query(ElasticsearchQueryString.of("needle"))
                .searchTypes(Set.of(
                                MessageList.builder()
                                        .id("messagelist-1")
                                        .build(),
                                Pivot.builder()
                                        .id("pivot-1")
                                        .rowGroups(Time.builder().field("source").interval(AutoInterval.create()).build())
                                        .timerange(AbsoluteRange.create(DateTime.parse("2016-05-19T00:00:00.000Z"), DateTime.parse("2022-01-09T00:00:00.000Z")))
                                        .series()
                                        .rollup(false)
                                        .build()
                        )
                )
                .timerange(RelativeRange.create(300))
                .build();
        final Search search = Search.builder().queries(ImmutableSet.of(query)).build();
        final SearchJob job = new SearchJob("deadbeef", search, "admin", "test-node-id");
        final GeneratedQueryContext generatedQueryContext = createContext(query);

        var explainResult = backend.explain(job, query, generatedQueryContext);
        assertThat(explainResult.searchTypes()).isNotNull();
        assertThat(explainResult.searchTypes().get("messagelist-1")).satisfies(ml -> {
            assertThat(ml).isNotNull();

            assertThat(ml.searchedIndexRanges()).hasSize(1);
            assertThat(ml.searchedIndexRanges()).allMatch(r -> r.indexName().equals("graylog_0"));


            var ctx = JsonPath.parse(ml.queryString());
            JsonPathAssert.assertThat(ctx).jsonPathAsString("$.query.bool.must[0].bool.filter[0].query_string.query").isEqualTo("needle");
        });

        assertThat(explainResult.searchTypes().get("pivot-1")).satisfies(ml -> {
            assertThat(ml).isNotNull();
            assertThat(ml.searchedIndexRanges()).hasSize(3);
            assertThat(ml.searchedIndexRanges()).anyMatch(r -> r.indexName().equals("graylog_0") && !r.isWarmTiered());
            assertThat(ml.searchedIndexRanges()).anyMatch(r -> r.indexName().equals("graylog_warm_2") && r.isWarmTiered());

            var ctx = JsonPath.parse(ml.queryString());
            JsonPathAssert.assertThat(ctx).jsonPathAsString("$.query.bool.must[0].bool.filter[0].query_string.query").isEqualTo("needle");
            JsonPathAssert.assertThat(ctx).jsonPathAsString("$.aggregations.agg.date_histogram.field").isEqualTo("source");
        });
    }