Skip to content

Conversation

@not-napoleon
Copy link
Member

@not-napoleon not-napoleon commented Aug 11, 2025

Fetch all dimensions when running a time series query

Note on CCS - this is adding a filter to field caps, which will not be available on older versions. This will cause the CCS field caps request to fail for those clusters. However, since the TS command this supports will not be released until after this is merged, that will only happen on clusters that weren't going to be able to run the query anyway. This seems acceptable to me, but worth mentioning.

@not-napoleon not-napoleon added >enhancement WIP v9.2.0 :StorageEngine/ES|QL Timeseries / metrics / logsdb capabilities in ES|QL labels Aug 11, 2025
// Detect if we are in TS mode
List<LogicalPlan> relations = parsed.collect(UnresolvedRelation.class::isInstance);
for (LogicalPlan i : relations) {
if (((UnresolvedRelation) i).isTimeSeriesMode()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast should be completely safe, since the collect above should only have returned UnresolvedRelation instances.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can avoid casting with this:

boolean shouldCollectAllDimensions = 
         parsed.collectFirstChildren(c -> c instanceof UnresolvedRelation ur && ur.isTimeSeriesMode()).isEmpty() == false;

@not-napoleon not-napoleon marked this pull request as ready for review August 14, 2025 17:25
Copy link
Member

@dnhatn dnhatn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments, but the approach looks great. Thanks Mark!

final String field = entry.getKey();
if (fieldNameFilter.test(field) == false) {
MappedFieldType ft = entry.getValue();
if (fieldNameFilter.test(field) == false && ((ft.isDimension() && includeDimensions) == false)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move includeDimensions before ft.isDimension() since it's much cheaper?

l.onResponse(result.withIndexResolution(indexResolution));
})
}),
false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to use true for time-series mode here?

// Detect if we are in TS mode
List<LogicalPlan> relations = parsed.collect(UnresolvedRelation.class::isInstance);
for (LogicalPlan i : relations) {
if (((UnresolvedRelation) i).isTimeSeriesMode()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can avoid casting with this:

boolean shouldCollectAllDimensions = 
         parsed.collectFirstChildren(c -> c instanceof UnresolvedRelation ur && ur.isTimeSeriesMode()).isEmpty() == false;

Set<String> wildcardJoinIndices,
InferenceResolution inferenceResolution
InferenceResolution inferenceResolution,
boolean collectAllDimensions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to add this flag to PreAnalyzer.PreAnalysis instead? We already have an index mode in PreAnalyzer.PreAnalysis; shouldn't that be sufficient?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, upon review I don't think we need this at all. As you say, the index mode in the PreAnalyzer.PreAnalysis should be enough.

Copy link
Contributor

@romseygeek romseygeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I had a look around and it seems we don't publicly document the accepted filter values anywhere. Do you think this is intentional? I feel we ought to at least have a javadoc entry somewhere.


private static boolean checkIncludeDimensions(String[] filters) {
for (String filter : filters) {
if ("+dimension".equals(filter)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: +dimensions reads better to me? +dimension implies that there is only one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although having said that, we already have +parent that can return multiple parents, so maybe it's fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I had been following the "convention" from +parent, but I don't feel strongly one way or the other.

@not-napoleon
Copy link
Member Author

I feel we ought to at least have a javadoc entry somewhere.

IMHO, it should be an enum. I have a strong dislike of magic strings. I have a mind to refactor that on a slow Friday.

@not-napoleon not-napoleon requested a review from dnhatn August 21, 2025 15:06
Copy link
Member

@dnhatn dnhatn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks Mark!

@not-napoleon not-napoleon enabled auto-merge (squash) August 22, 2025 14:36
@not-napoleon not-napoleon merged commit 6448c1c into elastic:main Aug 27, 2025
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>enhancement :StorageEngine/ES|QL Timeseries / metrics / logsdb capabilities in ES|QL v9.2.0 WIP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants