Skip to content

Commit e429aa7

Browse files
sandeshkr419abhita
authored andcommitted
[Star Tree] [Search] Support of Date Range Queries in Aggregations (opensearch-project#17855)
* support for date range boolean queries Signed-off-by: Sandesh Kumar <[email protected]>
1 parent 0d9cacc commit e429aa7

26 files changed

+1432
-425
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4242
- Added File Cache Pinning ([#17617](https://github.com/opensearch-project/OpenSearch/issues/13648))
4343
- Support consumer reset in Resume API for pull-based ingestion. This PR includes a breaking change for the experimental pull-based ingestion feature. ([#18332](https://github.com/opensearch-project/OpenSearch/pull/18332))
4444
- Add FIPS build tooling ([#4254](https://github.com/opensearch-project/security/issues/4254))
45+
- [Star-Tree] Support for date-range queries with star-tree supported aggregations ([#17855](https://github.com/opensearch-project/OpenSearch/pull/17855)
4546

4647
### Changed
4748
- Create generic DocRequest to better categorize ActionRequests ([#18269](https://github.com/opensearch-project/OpenSearch/pull/18269)))

server/src/main/java/org/opensearch/index/query/RangeQueryBuilder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.lucene.search.MatchNoDocsQuery;
3636
import org.apache.lucene.search.Query;
3737
import org.apache.lucene.util.BytesRef;
38+
import org.opensearch.common.annotation.PublicApi;
3839
import org.opensearch.common.geo.ShapeRelation;
3940
import org.opensearch.common.time.DateFormatter;
4041
import org.opensearch.common.time.DateMathParser;
@@ -56,10 +57,12 @@
5657
import java.util.Objects;
5758

5859
/**
59-
* A Query that matches documents within an range of terms.
60+
* A Query that matches documents within a range of terms.
6061
*
6162
* @opensearch.internal
6263
*/
64+
// TODO: Revert @PublicApi annotation after @ExperimentalApi is removed from DimensionFilterMapper
65+
@PublicApi(since = "1.0.0")
6366
public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> implements MultiTermQueryBuilder {
6467
public static final String NAME = "range";
6568

server/src/main/java/org/opensearch/search/aggregations/bucket/histogram/DateHistogramAggregator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
import org.opensearch.search.internal.SearchContext;
6767
import org.opensearch.search.startree.StarTreeQueryHelper;
6868
import org.opensearch.search.startree.StarTreeTraversalUtil;
69-
import org.opensearch.search.startree.filter.DimensionFilter;
69+
import org.opensearch.search.startree.filter.MatchAllFilter;
7070

7171
import java.io.IOException;
7272
import java.util.Collections;
@@ -301,8 +301,8 @@ public StarTreeBucketCollector getStarTreeBucketCollector(
301301
starTreeValues,
302302
StarTreeQueryHelper.mergeDimensionFilterIfNotExists(
303303
context.getQueryShardContext().getStarTreeQueryContext().getBaseQueryStarTreeFilter(),
304-
starTreeDateDimension,
305-
List.of(DimensionFilter.MATCH_ALL_DEFAULT)
304+
fieldName,
305+
List.of(new MatchAllFilter(fieldName, starTreeDateDimension))
306306
),
307307
context
308308
)

server/src/main/java/org/opensearch/search/aggregations/bucket/range/RangeAggregator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
import org.opensearch.search.internal.SearchContext;
7272
import org.opensearch.search.startree.StarTreeQueryHelper;
7373
import org.opensearch.search.startree.StarTreeTraversalUtil;
74-
import org.opensearch.search.startree.filter.DimensionFilter;
74+
import org.opensearch.search.startree.filter.MatchAllFilter;
7575

7676
import java.io.IOException;
7777
import java.util.ArrayList;
@@ -396,7 +396,7 @@ public StarTreeBucketCollector getStarTreeBucketCollector(
396396
StarTreeQueryHelper.mergeDimensionFilterIfNotExists(
397397
context.getQueryShardContext().getStarTreeQueryContext().getBaseQueryStarTreeFilter(),
398398
fieldName,
399-
List.of(DimensionFilter.MATCH_ALL_DEFAULT)
399+
List.of(new MatchAllFilter(fieldName))
400400
),
401401
context
402402
)

server/src/main/java/org/opensearch/search/aggregations/bucket/terms/GlobalOrdinalsStringTermsAggregator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
import org.opensearch.search.internal.SearchContext;
7777
import org.opensearch.search.startree.StarTreeQueryHelper;
7878
import org.opensearch.search.startree.StarTreeTraversalUtil;
79-
import org.opensearch.search.startree.filter.DimensionFilter;
79+
import org.opensearch.search.startree.filter.MatchAllFilter;
8080

8181
import java.io.IOException;
8282
import java.util.Arrays;
@@ -343,7 +343,7 @@ public StarTreeBucketCollector getStarTreeBucketCollector(
343343
StarTreeQueryHelper.mergeDimensionFilterIfNotExists(
344344
context.getQueryShardContext().getStarTreeQueryContext().getBaseQueryStarTreeFilter(),
345345
fieldName,
346-
List.of(DimensionFilter.MATCH_ALL_DEFAULT)
346+
List.of(new MatchAllFilter(fieldName))
347347
),
348348
context
349349
)

server/src/main/java/org/opensearch/search/aggregations/bucket/terms/NumericTermsAggregator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
import org.opensearch.search.internal.SearchContext;
6969
import org.opensearch.search.startree.StarTreeQueryHelper;
7070
import org.opensearch.search.startree.StarTreeTraversalUtil;
71-
import org.opensearch.search.startree.filter.DimensionFilter;
71+
import org.opensearch.search.startree.filter.MatchAllFilter;
7272

7373
import java.io.IOException;
7474
import java.math.BigInteger;
@@ -187,7 +187,7 @@ public StarTreeBucketCollector getStarTreeBucketCollector(
187187
StarTreeQueryHelper.mergeDimensionFilterIfNotExists(
188188
context.getQueryShardContext().getStarTreeQueryContext().getBaseQueryStarTreeFilter(),
189189
fieldName,
190-
List.of(DimensionFilter.MATCH_ALL_DEFAULT)
190+
List.of(new MatchAllFilter(fieldName))
191191
),
192192
context
193193
)

server/src/main/java/org/opensearch/search/startree/StarTreeTraversalUtil.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@ public static FixedBitSet getStarTreeResult(StarTreeValues starTreeValues, StarT
8484
for (String remainingPredicateColumn : starTreeResult.remainingPredicateColumns) {
8585
logger.debug("remainingPredicateColumn : {}, maxMatchedDoc : {} ", remainingPredicateColumn, starTreeResult.maxMatchedDoc);
8686

87-
StarTreeValuesIterator valuesIterator = starTreeValues.getDimensionValuesIterator(remainingPredicateColumn);
8887
// Get the query value directly
8988
List<DimensionFilter> dimensionFilters = starTreeFilter.getFiltersForDimension(remainingPredicateColumn);
89+
StarTreeValuesIterator valuesIterator = starTreeValues.getDimensionValuesIterator(
90+
dimensionFilters.getFirst().getMatchingDimension()
91+
);
9092

9193
// Clear the temporary bit set before reuse
9294
tempBitSet.clear(0, starTreeResult.maxMatchedDoc + 1);
@@ -131,7 +133,7 @@ private static StarTreeResult traverseStarTree(StarTreeValues starTreeValues, St
131133
Queue<StarTreeNode> queue = new ArrayDeque<>();
132134
queue.add(starTree);
133135
int currentDimensionId = -1;
134-
Set<String> remainingPredicateColumns = new HashSet<>(starTreeFilter.getDimensions());
136+
Set<String> remainingPredicateColumns = new HashSet<>(starTreeFilter.getMatchingDimensions());
135137
int matchedDocsCountInStarTree = 0;
136138
int maxDocNum = -1;
137139
StarTreeNode starTreeNode;

server/src/main/java/org/opensearch/search/startree/filter/DimensionFilter.java

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,16 @@
1111
import org.opensearch.common.annotation.ExperimentalApi;
1212
import org.opensearch.index.compositeindex.datacube.startree.index.StarTreeValues;
1313
import org.opensearch.index.compositeindex.datacube.startree.node.StarTreeNode;
14-
import org.opensearch.index.compositeindex.datacube.startree.node.StarTreeNodeType;
1514
import org.opensearch.search.internal.SearchContext;
1615
import org.opensearch.search.startree.StarTreeNodeCollector;
1716

1817
import java.io.IOException;
19-
import java.util.Iterator;
2018

2119
/**
2220
* Contains the logic to filter over a dimension either in StarTree Index or it's Dimension DocValues
2321
*/
2422
@ExperimentalApi
2523
public interface DimensionFilter {
26-
27-
DimensionFilter MATCH_ALL_DEFAULT = new DimensionFilter() {
28-
@Override
29-
public void initialiseForSegment(StarTreeValues starTreeValues, SearchContext searchContext) throws IOException {
30-
31-
}
32-
33-
@Override
34-
public void matchStarTreeNodes(StarTreeNode parentNode, StarTreeValues starTreeValues, StarTreeNodeCollector collector)
35-
throws IOException {
36-
if (parentNode != null) {
37-
for (Iterator<? extends StarTreeNode> it = parentNode.getChildrenIterator(); it.hasNext();) {
38-
StarTreeNode starTreeNode = it.next();
39-
if (starTreeNode.getStarTreeNodeType() == StarTreeNodeType.DEFAULT.getValue()) {
40-
collector.collectStarTreeNode(starTreeNode);
41-
}
42-
}
43-
}
44-
}
45-
46-
@Override
47-
public boolean matchDimValue(long ordinal, StarTreeValues starTreeValues) {
48-
return true;
49-
}
50-
};
51-
5224
/**
5325
* Converts parsed user values to ordinals based on segment and other init actions can be performed.
5426
* @param starTreeValues : Segment specific star tree root node and other metadata
@@ -74,10 +46,16 @@ public boolean matchDimValue(long ordinal, StarTreeValues starTreeValues) {
7446
*/
7547
boolean matchDimValue(long ordinal, StarTreeValues starTreeValues);
7648

77-
default String getDimensionName() {
49+
String getDimensionName();
50+
51+
default String getSubDimensionName() {
7852
return null;
7953
}
8054

55+
default String getMatchingDimension() {
56+
return getSubDimensionName() == null ? getDimensionName() : getSubDimensionName();
57+
}
58+
8159
/**
8260
* Represents how to match a value when comparing during StarTreeTraversal
8361
*/
@@ -89,5 +67,4 @@ enum MatchType {
8967
LTE,
9068
EXACT
9169
}
92-
9370
}

server/src/main/java/org/opensearch/search/startree/filter/DimensionFilterMergerUtils.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,16 @@ private static DimensionFilter intersectRangeFilters(
133133
}
134134
}
135135

136-
return new RangeMatchDimFilter(range1.getDimensionName(), newLow, newHigh, includeLow, includeHigh);
136+
String effectiveSubDimension = mapper.resolveUsingSubDimension()
137+
? mapper.getSubDimensionFieldEffective(range1.getSubDimensionName(), range2.getSubDimensionName())
138+
: null;
139+
140+
return new RangeMatchDimFilter(range1.getDimensionName(), newLow, newHigh, includeLow, includeHigh) {
141+
@Override
142+
public String getSubDimensionName() {
143+
return effectiveSubDimension;
144+
}
145+
};
137146
}
138147

139148
/**

server/src/main/java/org/opensearch/search/startree/filter/ExactMatchDimFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public void initialiseForSegment(StarTreeValues starTreeValues, SearchContext se
5050
starTreeValues.getStarTreeField().getDimensionsOrder()
5151
);
5252
this.dimensionFilterMapper = DimensionFilterMapper.Factory.fromMappedFieldType(
53-
searchContext.mapperService().fieldType(dimensionName)
53+
searchContext.mapperService().fieldType(dimensionName),
54+
searchContext
5455
);
5556

5657
for (Object rawValue : rawValues) {

0 commit comments

Comments
 (0)