-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HSEARCH-5133 Support ES metric numeric aggregations
- Loading branch information
Showing
49 changed files
with
1,575 additions
and
0 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
...h/backend/elasticsearch/search/aggregation/impl/ElasticsearchMetricDoubleAggregation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.search.backend.elasticsearch.search.aggregation.impl; | ||
|
||
import org.hibernate.search.backend.elasticsearch.search.common.impl.AbstractElasticsearchCodecAwareSearchQueryElementFactory; | ||
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexScope; | ||
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexValueFieldContext; | ||
import org.hibernate.search.backend.elasticsearch.types.codec.impl.ElasticsearchDoubleFieldCodec; | ||
import org.hibernate.search.backend.elasticsearch.types.codec.impl.ElasticsearchFieldCodec; | ||
import org.hibernate.search.engine.search.aggregation.spi.SearchFilterableAggregationBuilder; | ||
|
||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
|
||
public class ElasticsearchMetricDoubleAggregation extends AbstractElasticsearchNestableAggregation<Double> { | ||
|
||
private final String absoluteFieldPath; | ||
private final String operation; | ||
|
||
public ElasticsearchMetricDoubleAggregation(Builder builder) { | ||
super( builder ); | ||
this.absoluteFieldPath = builder.field.absolutePath(); | ||
this.operation = builder.operation; | ||
} | ||
|
||
@Override | ||
protected final JsonObject doRequest(AggregationRequestContext context) { | ||
JsonObject outerObject = new JsonObject(); | ||
JsonObject innerObject = new JsonObject(); | ||
|
||
outerObject.add( operation, innerObject ); | ||
innerObject.addProperty( "field", absoluteFieldPath ); | ||
return outerObject; | ||
} | ||
|
||
@Override | ||
protected Extractor<Double> extractor(AggregationRequestContext context) { | ||
return new MetricDoubleExtractor(); | ||
} | ||
|
||
public static class Factory<F> | ||
extends | ||
AbstractElasticsearchCodecAwareSearchQueryElementFactory<SearchFilterableAggregationBuilder<Double>, F> { | ||
|
||
private final String operation; | ||
|
||
public Factory(ElasticsearchFieldCodec<F> codec, String operation) { | ||
super( codec ); | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public SearchFilterableAggregationBuilder<Double> create(ElasticsearchSearchIndexScope<?> scope, | ||
ElasticsearchSearchIndexValueFieldContext<F> field) { | ||
return new Builder( scope, field, operation ); | ||
} | ||
} | ||
|
||
private static class MetricDoubleExtractor implements Extractor<Double> { | ||
@Override | ||
public Double extract(JsonObject aggregationResult, AggregationExtractContext context) { | ||
JsonElement value = aggregationResult.get( "value" ); | ||
return ElasticsearchDoubleFieldCodec.INSTANCE.decode( value ); | ||
} | ||
} | ||
|
||
private static class Builder extends AbstractBuilder<Double> implements SearchFilterableAggregationBuilder<Double> { | ||
private final String operation; | ||
|
||
private Builder(ElasticsearchSearchIndexScope<?> scope, ElasticsearchSearchIndexValueFieldContext<?> field, | ||
String operation) { | ||
super( scope, field ); | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public ElasticsearchMetricDoubleAggregation build() { | ||
return new ElasticsearchMetricDoubleAggregation( this ); | ||
} | ||
} | ||
} |
128 changes: 128 additions & 0 deletions
128
...ch/backend/elasticsearch/search/aggregation/impl/ElasticsearchMetricFieldAggregation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.search.backend.elasticsearch.search.aggregation.impl; | ||
|
||
import org.hibernate.search.backend.elasticsearch.search.common.impl.AbstractElasticsearchCodecAwareSearchQueryElementFactory; | ||
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexScope; | ||
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexValueFieldContext; | ||
import org.hibernate.search.backend.elasticsearch.types.codec.impl.ElasticsearchFieldCodec; | ||
import org.hibernate.search.engine.backend.types.converter.runtime.FromDocumentValueConvertContext; | ||
import org.hibernate.search.engine.backend.types.converter.spi.ProjectionConverter; | ||
import org.hibernate.search.engine.search.aggregation.spi.FieldMetricAggregationBuilder; | ||
import org.hibernate.search.engine.search.common.ValueConvert; | ||
|
||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
|
||
/** | ||
* @param <F> The type of field values. | ||
* @param <K> The type of returned value. It can be {@code F} | ||
* or a different type if value converters are used. | ||
*/ | ||
public class ElasticsearchMetricFieldAggregation<F, K> extends AbstractElasticsearchNestableAggregation<K> { | ||
|
||
private final String absoluteFieldPath; | ||
private final ProjectionConverter<F, ? extends K> fromFieldValueConverter; | ||
private final ElasticsearchFieldCodec<F> codec; | ||
private final String operation; | ||
|
||
public ElasticsearchMetricFieldAggregation(Builder<F, K> builder) { | ||
super( builder ); | ||
this.absoluteFieldPath = builder.field.absolutePath(); | ||
this.fromFieldValueConverter = builder.fromFieldValueConverter; | ||
this.codec = builder.codec; | ||
this.operation = builder.operation; | ||
} | ||
|
||
@Override | ||
protected final JsonObject doRequest(AggregationRequestContext context) { | ||
JsonObject outerObject = new JsonObject(); | ||
JsonObject innerObject = new JsonObject(); | ||
|
||
outerObject.add( operation, innerObject ); | ||
innerObject.addProperty( "field", absoluteFieldPath ); | ||
return outerObject; | ||
} | ||
|
||
@Override | ||
protected Extractor<K> extractor(AggregationRequestContext context) { | ||
return new MetricFieldExtractor(); | ||
} | ||
|
||
public static class Factory<F> | ||
extends AbstractElasticsearchCodecAwareSearchQueryElementFactory<FieldMetricAggregationBuilder.TypeSelector, F> { | ||
|
||
private final String operation; | ||
|
||
public Factory(ElasticsearchFieldCodec<F> codec, String operation) { | ||
super( codec ); | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public FieldMetricAggregationBuilder.TypeSelector create(ElasticsearchSearchIndexScope<?> scope, | ||
ElasticsearchSearchIndexValueFieldContext<F> field) { | ||
return new ElasticsearchMetricFieldAggregation.TypeSelector<>( codec, scope, field, operation ); | ||
} | ||
} | ||
|
||
private static class TypeSelector<F> implements FieldMetricAggregationBuilder.TypeSelector { | ||
private final ElasticsearchFieldCodec<F> codec; | ||
private final ElasticsearchSearchIndexScope<?> scope; | ||
private final ElasticsearchSearchIndexValueFieldContext<F> field; | ||
private final String operation; | ||
|
||
private TypeSelector(ElasticsearchFieldCodec<F> codec, | ||
ElasticsearchSearchIndexScope<?> scope, ElasticsearchSearchIndexValueFieldContext<F> field, | ||
String operation) { | ||
this.codec = codec; | ||
this.scope = scope; | ||
this.field = field; | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public <T> Builder<F, T> type(Class<T> expectedType, ValueConvert convert) { | ||
return new Builder<>( codec, scope, field, | ||
field.type().projectionConverter( convert ).withConvertedType( expectedType, field ), | ||
operation ); | ||
} | ||
} | ||
|
||
private class MetricFieldExtractor implements Extractor<K> { | ||
@Override | ||
public K extract(JsonObject aggregationResult, AggregationExtractContext context) { | ||
FromDocumentValueConvertContext convertContext = context.fromDocumentValueConvertContext(); | ||
JsonElement value = aggregationResult.get( "value" ); | ||
JsonElement valueAsString = aggregationResult.get( "value_as_string" ); | ||
return fromFieldValueConverter.fromDocumentValue( | ||
codec.decodeAggregationValue( value, valueAsString ), | ||
convertContext | ||
); | ||
} | ||
} | ||
|
||
private static class Builder<F, K> extends AbstractBuilder<K> | ||
implements FieldMetricAggregationBuilder<K> { | ||
|
||
private final ElasticsearchFieldCodec<F> codec; | ||
private final ProjectionConverter<F, ? extends K> fromFieldValueConverter; | ||
private final String operation; | ||
|
||
private Builder(ElasticsearchFieldCodec<F> codec, ElasticsearchSearchIndexScope<?> scope, | ||
ElasticsearchSearchIndexValueFieldContext<F> field, | ||
ProjectionConverter<F, ? extends K> fromFieldValueConverter, String operation) { | ||
super( scope, field ); | ||
this.codec = codec; | ||
this.fromFieldValueConverter = fromFieldValueConverter; | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public ElasticsearchMetricFieldAggregation<F, K> build() { | ||
return new ElasticsearchMetricFieldAggregation<>( this ); | ||
} | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
...rch/backend/elasticsearch/search/aggregation/impl/ElasticsearchMetricLongAggregation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.search.backend.elasticsearch.search.aggregation.impl; | ||
|
||
import org.hibernate.search.backend.elasticsearch.search.common.impl.AbstractElasticsearchCodecAwareSearchQueryElementFactory; | ||
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexScope; | ||
import org.hibernate.search.backend.elasticsearch.search.common.impl.ElasticsearchSearchIndexValueFieldContext; | ||
import org.hibernate.search.backend.elasticsearch.types.codec.impl.ElasticsearchFieldCodec; | ||
import org.hibernate.search.backend.elasticsearch.types.codec.impl.ElasticsearchLongFieldCodec; | ||
import org.hibernate.search.engine.search.aggregation.spi.SearchFilterableAggregationBuilder; | ||
|
||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
|
||
public class ElasticsearchMetricLongAggregation extends AbstractElasticsearchNestableAggregation<Long> { | ||
|
||
private final String absoluteFieldPath; | ||
private final String operation; | ||
|
||
public ElasticsearchMetricLongAggregation(Builder builder) { | ||
super( builder ); | ||
this.absoluteFieldPath = builder.field.absolutePath(); | ||
this.operation = builder.operation; | ||
} | ||
|
||
@Override | ||
protected final JsonObject doRequest(AggregationRequestContext context) { | ||
JsonObject outerObject = new JsonObject(); | ||
JsonObject innerObject = new JsonObject(); | ||
|
||
outerObject.add( operation, innerObject ); | ||
innerObject.addProperty( "field", absoluteFieldPath ); | ||
return outerObject; | ||
} | ||
|
||
@Override | ||
protected Extractor<Long> extractor(AggregationRequestContext context) { | ||
return new MetricLongExtractor(); | ||
} | ||
|
||
public static class Factory<F> | ||
extends | ||
AbstractElasticsearchCodecAwareSearchQueryElementFactory<SearchFilterableAggregationBuilder<Long>, F> { | ||
|
||
private final String operation; | ||
|
||
public Factory(ElasticsearchFieldCodec<F> codec, String operation) { | ||
super( codec ); | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public SearchFilterableAggregationBuilder<Long> create(ElasticsearchSearchIndexScope<?> scope, | ||
ElasticsearchSearchIndexValueFieldContext<F> field) { | ||
return new Builder( scope, field, operation ); | ||
} | ||
} | ||
|
||
private static class MetricLongExtractor implements Extractor<Long> { | ||
@Override | ||
public Long extract(JsonObject aggregationResult, AggregationExtractContext context) { | ||
JsonElement value = aggregationResult.get( "value" ); | ||
return ElasticsearchLongFieldCodec.INSTANCE.decode( value ); | ||
} | ||
} | ||
|
||
private static class Builder extends AbstractBuilder<Long> implements SearchFilterableAggregationBuilder<Long> { | ||
private final String operation; | ||
|
||
private Builder(ElasticsearchSearchIndexScope<?> scope, ElasticsearchSearchIndexValueFieldContext<?> field, | ||
String operation) { | ||
super( scope, field ); | ||
this.operation = operation; | ||
} | ||
|
||
@Override | ||
public ElasticsearchMetricLongAggregation build() { | ||
return new ElasticsearchMetricLongAggregation( this ); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.