Skip to content

Commit 21be0fc

Browse files
bharath-techiedk2k
authored andcommitted
[Star tree] Changes to handle derived metrics such as avg as part of star tree mapping (opensearch-project#15152)
--------- Signed-off-by: Bharathwaj G <[email protected]>
1 parent 7f8a228 commit 21be0fc

File tree

6 files changed

+247
-47
lines changed

6 files changed

+247
-47
lines changed

server/src/internalClusterTest/java/org/opensearch/index/mapper/StarTreeMapperIT.java

+6-14
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,9 @@ public void testValidCompositeIndex() {
265265
assertEquals(expectedTimeUnits, dateDim.getIntervals());
266266
assertEquals("numeric_dv", starTreeFieldType.getDimensions().get(1).getField());
267267
assertEquals("numeric_dv", starTreeFieldType.getMetrics().get(0).getField());
268-
List<MetricStat> expectedMetrics = Arrays.asList(
269-
MetricStat.AVG,
270-
MetricStat.VALUE_COUNT,
271-
MetricStat.SUM,
272-
MetricStat.MAX,
273-
MetricStat.MIN
274-
);
268+
269+
// Assert default metrics
270+
List<MetricStat> expectedMetrics = Arrays.asList(MetricStat.VALUE_COUNT, MetricStat.SUM, MetricStat.AVG);
275271
assertEquals(expectedMetrics, starTreeFieldType.getMetrics().get(0).getMetrics());
276272
assertEquals(10000, starTreeFieldType.getStarTreeConfig().maxLeafDocs());
277273
assertEquals(
@@ -349,13 +345,9 @@ public void testUpdateIndexWhenMappingIsSame() {
349345
assertEquals(expectedTimeUnits, dateDim.getIntervals());
350346
assertEquals("numeric_dv", starTreeFieldType.getDimensions().get(1).getField());
351347
assertEquals("numeric_dv", starTreeFieldType.getMetrics().get(0).getField());
352-
List<MetricStat> expectedMetrics = Arrays.asList(
353-
MetricStat.AVG,
354-
MetricStat.VALUE_COUNT,
355-
MetricStat.SUM,
356-
MetricStat.MAX,
357-
MetricStat.MIN
358-
);
348+
349+
// Assert default metrics
350+
List<MetricStat> expectedMetrics = Arrays.asList(MetricStat.VALUE_COUNT, MetricStat.SUM, MetricStat.AVG);
359351
assertEquals(expectedMetrics, starTreeFieldType.getMetrics().get(0).getMetrics());
360352
assertEquals(10000, starTreeFieldType.getStarTreeConfig().maxLeafDocs());
361353
assertEquals(

server/src/main/java/org/opensearch/index/compositeindex/datacube/MetricStat.java

+24-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111
import org.opensearch.common.annotation.ExperimentalApi;
1212

13+
import java.util.Arrays;
14+
import java.util.List;
15+
1316
/**
1417
* Supported metric types for composite index
1518
*
@@ -18,21 +21,39 @@
1821
@ExperimentalApi
1922
public enum MetricStat {
2023
VALUE_COUNT("value_count"),
21-
AVG("avg"),
2224
SUM("sum"),
2325
MIN("min"),
24-
MAX("max");
26+
MAX("max"),
27+
AVG("avg", VALUE_COUNT, SUM);
2528

2629
private final String typeName;
30+
private final MetricStat[] baseMetrics;
2731

28-
MetricStat(String typeName) {
32+
MetricStat(String typeName, MetricStat... baseMetrics) {
2933
this.typeName = typeName;
34+
this.baseMetrics = baseMetrics;
3035
}
3136

3237
public String getTypeName() {
3338
return typeName;
3439
}
3540

41+
/**
42+
* Return the list of metrics that this metric is derived from
43+
* For example, AVG is derived from COUNT and SUM
44+
*/
45+
public List<MetricStat> getBaseMetrics() {
46+
return Arrays.asList(baseMetrics);
47+
}
48+
49+
/**
50+
* Return true if this metric is derived from other metrics
51+
* For example, AVG is derived from COUNT and SUM
52+
*/
53+
public boolean isDerivedMetric() {
54+
return baseMetrics != null && baseMetrics.length > 0;
55+
}
56+
3657
public static MetricStat fromTypeName(String typeName) {
3758
for (MetricStat metric : MetricStat.values()) {
3859
if (metric.getTypeName().equalsIgnoreCase(typeName)) {

server/src/main/java/org/opensearch/index/compositeindex/datacube/startree/StarTreeIndexSettings.java

+4-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import java.util.Arrays;
1717
import java.util.List;
18+
import java.util.function.Function;
1819

1920
/**
2021
* Index settings for star tree fields. The settings are final as right now
@@ -93,16 +94,10 @@ public class StarTreeIndexSettings {
9394
/**
9495
* Default metrics for metrics as part of star tree fields
9596
*/
96-
public static final Setting<List<MetricStat>> DEFAULT_METRICS_LIST = Setting.listSetting(
97+
public static final Setting<List<String>> DEFAULT_METRICS_LIST = Setting.listSetting(
9798
"index.composite_index.star_tree.field.default.metrics",
98-
Arrays.asList(
99-
MetricStat.AVG.toString(),
100-
MetricStat.VALUE_COUNT.toString(),
101-
MetricStat.SUM.toString(),
102-
MetricStat.MAX.toString(),
103-
MetricStat.MIN.toString()
104-
),
105-
MetricStat::fromTypeName,
99+
Arrays.asList(MetricStat.VALUE_COUNT.toString(), MetricStat.SUM.toString()),
100+
Function.identity(),
106101
Setting.Property.IndexScope,
107102
Setting.Property.Final
108103
);

server/src/main/java/org/opensearch/index/compositeindex/datacube/startree/builder/BaseStarTreeBuilder.java

+3
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ public List<MetricAggregatorInfo> generateMetricAggregatorInfos(MapperService ma
118118
List<MetricAggregatorInfo> metricAggregatorInfos = new ArrayList<>();
119119
for (Metric metric : this.starTreeField.getMetrics()) {
120120
for (MetricStat metricStat : metric.getMetrics()) {
121+
if (metricStat.isDerivedMetric()) {
122+
continue;
123+
}
121124
IndexNumericFieldData.NumericType numericType;
122125
Mapper fieldMapper = mapperService.documentMapper().mappers().getMapper(metric.getField());
123126
if (fieldMapper instanceof NumberFieldMapper) {

server/src/main/java/org/opensearch/index/mapper/StarTreeMapper.java

+41-7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Locale;
2929
import java.util.Map;
3030
import java.util.Optional;
31+
import java.util.Queue;
3132
import java.util.Set;
3233
import java.util.stream.Collectors;
3334

@@ -262,17 +263,50 @@ private Metric getMetric(String name, Map<String, Object> metric, Mapper.TypePar
262263
.collect(Collectors.toList());
263264
metric.remove(STATS);
264265
if (metricStrings.isEmpty()) {
265-
metricTypes = new ArrayList<>(StarTreeIndexSettings.DEFAULT_METRICS_LIST.get(context.getSettings()));
266-
} else {
267-
Set<MetricStat> metricSet = new LinkedHashSet<>();
268-
for (String metricString : metricStrings) {
269-
metricSet.add(MetricStat.fromTypeName(metricString));
270-
}
271-
metricTypes = new ArrayList<>(metricSet);
266+
metricStrings = new ArrayList<>(StarTreeIndexSettings.DEFAULT_METRICS_LIST.get(context.getSettings()));
267+
}
268+
// Add all required metrics initially
269+
Set<MetricStat> metricSet = new LinkedHashSet<>();
270+
for (String metricString : metricStrings) {
271+
MetricStat metricStat = MetricStat.fromTypeName(metricString);
272+
metricSet.add(metricStat);
273+
addBaseMetrics(metricStat, metricSet);
272274
}
275+
addEligibleDerivedMetrics(metricSet);
276+
metricTypes = new ArrayList<>(metricSet);
273277
return new Metric(name, metricTypes);
274278
}
275279

280+
/**
281+
* Add base metrics of derived metric to metric set
282+
*/
283+
private void addBaseMetrics(MetricStat metricStat, Set<MetricStat> metricSet) {
284+
if (metricStat.isDerivedMetric()) {
285+
Queue<MetricStat> metricQueue = new LinkedList<>(metricStat.getBaseMetrics());
286+
while (metricQueue.isEmpty() == false) {
287+
MetricStat metric = metricQueue.poll();
288+
if (metric.isDerivedMetric() && !metricSet.contains(metric)) {
289+
metricQueue.addAll(metric.getBaseMetrics());
290+
}
291+
metricSet.add(metric);
292+
}
293+
}
294+
}
295+
296+
/**
297+
* Add derived metrics if all associated base metrics are present
298+
*/
299+
private void addEligibleDerivedMetrics(Set<MetricStat> metricStats) {
300+
for (MetricStat metric : MetricStat.values()) {
301+
if (metric.isDerivedMetric() && !metricStats.contains(metric)) {
302+
List<MetricStat> sourceMetrics = metric.getBaseMetrics();
303+
if (metricStats.containsAll(sourceMetrics)) {
304+
metricStats.add(metric);
305+
}
306+
}
307+
}
308+
}
309+
276310
@Override
277311
protected List<Parameter<?>> getParameters() {
278312
return List.of(config);

0 commit comments

Comments
 (0)