mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-02 17:09:18 +00:00
Fix max/min aggs for unsigned_long (#63904)
Max and min aggs were producing wrong results for unsigned_long field if field was indexed. If field is indexed for max/min aggs instead of field data, we use values from indexed Points, values of which are derived using method pointReaderIfPossible. Before UnsignedLongFieldType#pointReaderIfPossible was incorrectly producing values, as it failed to shift them back to original values. This patch fixes method pointReaderIfPossible to produce correct original values. Relates to #60050
This commit is contained in:
parent
3369216087
commit
1287df4074
@ -49,6 +49,8 @@ import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.elasticsearch.xpack.unsignedlong.UnsignedLongLeafFieldData.convertUnsignedLongToDouble;
|
||||
|
||||
public class UnsignedLongFieldMapper extends ParametrizedFieldMapper {
|
||||
public static final String CONTENT_TYPE = "unsigned_long";
|
||||
|
||||
@ -272,7 +274,8 @@ public class UnsignedLongFieldMapper extends ParametrizedFieldMapper {
|
||||
@Override
|
||||
public Function<byte[], Number> pointReaderIfPossible() {
|
||||
if (isSearchable()) {
|
||||
return (value) -> LongPoint.decodeDimension(value, 0);
|
||||
// convert from the shifted value back to the original value
|
||||
return (value) -> convertUnsignedLongToDouble(LongPoint.decodeDimension(value, 0));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -520,7 +523,7 @@ public class UnsignedLongFieldMapper extends ParametrizedFieldMapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an unsigned long to the singed long by subtract 2^63 from it
|
||||
* Convert an unsigned long to the signed long by subtract 2^63 from it
|
||||
* @param value – unsigned long value in the range [0; 2^64-1], values greater than 2^63-1 are negative
|
||||
* @return signed long value in the range [-2^63; 2^63-1]
|
||||
*/
|
||||
|
@ -112,7 +112,7 @@ public class UnsignedLongLeafFieldData implements LeafNumericFieldData {
|
||||
};
|
||||
}
|
||||
|
||||
private static double convertUnsignedLongToDouble(long value) {
|
||||
static double convertUnsignedLongToDouble(long value) {
|
||||
if (value < 0L) {
|
||||
return sortableSignedLongToUnsigned(value); // add 2 ^ 63
|
||||
} else {
|
||||
|
@ -20,7 +20,9 @@ import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
||||
import org.elasticsearch.search.aggregations.bucket.range.Range;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
||||
import org.elasticsearch.search.aggregations.metrics.Min;
|
||||
import org.elasticsearch.search.aggregations.metrics.Sum;
|
||||
import org.elasticsearch.search.aggregations.metrics.Max;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
|
||||
@ -35,6 +37,8 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.range;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.min;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
|
||||
@ -279,6 +283,20 @@ public class UnsignedLongTests extends ESIntegTestCase {
|
||||
double expectedSum = Arrays.stream(values).mapToDouble(Number::doubleValue).sum();
|
||||
assertEquals(expectedSum, sum.getValue(), 0.001);
|
||||
}
|
||||
// max agg
|
||||
{
|
||||
SearchResponse response = client().prepareSearch("idx").setSize(0).addAggregation(max("ul_max").field("ul_field")).get();
|
||||
assertSearchResponse(response);
|
||||
Max max = response.getAggregations().get("ul_max");
|
||||
assertEquals(1.8446744073709551615E19, max.getValue(), 0.001);
|
||||
}
|
||||
// min agg
|
||||
{
|
||||
SearchResponse response = client().prepareSearch("idx").setSize(0).addAggregation(min("ul_min").field("ul_field")).get();
|
||||
assertSearchResponse(response);
|
||||
Min min = response.getAggregations().get("ul_min");
|
||||
assertEquals(0, min.getValue(), 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSortDifferentFormatsShouldFail() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user