Add parsing to Significant Terms aggregations (#24682)

Related to  #23331
This commit is contained in:
Tanguy Leroux 2017-05-16 14:54:42 +02:00 committed by GitHub
parent ef7c2e62c3
commit d5fc520741
10 changed files with 432 additions and 27 deletions

View File

@ -44,8 +44,8 @@ import java.util.Objects;
public abstract class InternalSignificantTerms<A extends InternalSignificantTerms<A, B>, B extends InternalSignificantTerms.Bucket<B>> public abstract class InternalSignificantTerms<A extends InternalSignificantTerms<A, B>, B extends InternalSignificantTerms.Bucket<B>>
extends InternalMultiBucketAggregation<A, B> implements SignificantTerms, ToXContent { extends InternalMultiBucketAggregation<A, B> implements SignificantTerms, ToXContent {
private static final String SCORE = "score"; public static final String SCORE = "score";
private static final String BG_COUNT = "bg_count"; public static final String BG_COUNT = "bg_count";
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod") @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
public abstract static class Bucket<B extends Bucket<B>> extends InternalMultiBucketAggregation.InternalBucket public abstract static class Bucket<B extends Bucket<B>> extends InternalMultiBucketAggregation.InternalBucket

View File

@ -0,0 +1,87 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.aggregations.bucket.significant;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
public class ParsedSignificantLongTerms extends ParsedSignificantTerms {
@Override
public String getType() {
return SignificantLongTerms.NAME;
}
private static ObjectParser<ParsedSignificantLongTerms, Void> PARSER =
new ObjectParser<>(ParsedSignificantLongTerms.class.getSimpleName(), true, ParsedSignificantLongTerms::new);
static {
declareParsedSignificantTermsFields(PARSER, ParsedBucket::fromXContent);
}
public static ParsedSignificantLongTerms fromXContent(XContentParser parser, String name) throws IOException {
ParsedSignificantLongTerms aggregation = PARSER.parse(parser, null);
aggregation.setName(name);
return aggregation;
}
public static class ParsedBucket extends ParsedSignificantTerms.ParsedBucket {
private Long key;
@Override
public Object getKey() {
return key;
}
@Override
public String getKeyAsString() {
String keyAsString = super.getKeyAsString();
if (keyAsString != null) {
return keyAsString;
}
return Long.toString(key);
}
public Number getKeyAsNumber() {
return key;
}
@Override
public int compareTerm(SignificantTerms.Bucket other) {
return key.compareTo(((ParsedBucket) other).key);
}
@Override
protected XContentBuilder keyToXContent(XContentBuilder builder) throws IOException {
builder.field(CommonFields.KEY.getPreferredName(), key);
if (super.getKeyAsString() != null) {
builder.field(CommonFields.KEY_AS_STRING.getPreferredName(), getKeyAsString());
}
return builder;
}
static ParsedBucket fromXContent(XContentParser parser) throws IOException {
return parseSignificantTermsBucketXContent(parser, new ParsedBucket(), (p, bucket) -> bucket.key = p.longValue());
}
}
}

View File

@ -0,0 +1,84 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.aggregations.bucket.significant;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
public class ParsedSignificantStringTerms extends ParsedSignificantTerms {
@Override
public String getType() {
return SignificantStringTerms.NAME;
}
private static ObjectParser<ParsedSignificantStringTerms, Void> PARSER =
new ObjectParser<>(ParsedSignificantStringTerms.class.getSimpleName(), true, ParsedSignificantStringTerms::new);
static {
declareParsedSignificantTermsFields(PARSER, ParsedBucket::fromXContent);
}
public static ParsedSignificantStringTerms fromXContent(XContentParser parser, String name) throws IOException {
ParsedSignificantStringTerms aggregation = PARSER.parse(parser, null);
aggregation.setName(name);
return aggregation;
}
public static class ParsedBucket extends ParsedSignificantTerms.ParsedBucket {
private BytesRef key;
@Override
public Object getKey() {
return getKeyAsString();
}
@Override
public String getKeyAsString() {
String keyAsString = super.getKeyAsString();
if (keyAsString != null) {
return keyAsString;
}
return key.utf8ToString();
}
public Number getKeyAsNumber() {
return Double.parseDouble(key.utf8ToString());
}
@Override
public int compareTerm(SignificantTerms.Bucket other) {
return key.compareTo(((ParsedBucket) other).key);
}
@Override
protected XContentBuilder keyToXContent(XContentBuilder builder) throws IOException {
return builder.field(CommonFields.KEY.getPreferredName(), getKey());
}
static ParsedBucket fromXContent(XContentParser parser) throws IOException {
return parseSignificantTermsBucketXContent(parser, new ParsedBucket(), (p, bucket) -> bucket.key = p.utf8BytesOrNull());
}
}
}

View File

@ -0,0 +1,166 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.aggregations.bucket.significant;
import org.elasticsearch.common.CheckedBiConsumer;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParserUtils;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.ParsedMultiBucketAggregation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public abstract class ParsedSignificantTerms extends ParsedMultiBucketAggregation<ParsedSignificantTerms.ParsedBucket>
implements SignificantTerms {
private Map<String, ParsedBucket> bucketMap;
protected long subsetSize;
protected long getSubsetSize() {
return subsetSize;
}
@Override
public List<? extends SignificantTerms.Bucket> getBuckets() {
return buckets;
}
@Override
public SignificantTerms.Bucket getBucketByKey(String term) {
if (bucketMap == null) {
bucketMap = buckets.stream().collect(Collectors.toMap(SignificantTerms.Bucket::getKeyAsString, Function.identity()));
}
return bucketMap.get(term);
}
@Override
public Iterator<SignificantTerms.Bucket> iterator() {
return buckets.stream().map(bucket -> (SignificantTerms.Bucket) bucket).collect(Collectors.toList()).iterator();
}
@Override
protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
builder.field(CommonFields.DOC_COUNT.getPreferredName(), subsetSize);
builder.startArray(CommonFields.BUCKETS.getPreferredName());
for (SignificantTerms.Bucket bucket : buckets) {
bucket.toXContent(builder, params);
}
builder.endArray();
return builder;
}
static void declareParsedSignificantTermsFields(final ObjectParser<? extends ParsedSignificantTerms, Void> objectParser,
final CheckedFunction<XContentParser, ParsedSignificantTerms.ParsedBucket, IOException> bucketParser) {
declareMultiBucketAggregationFields(objectParser, bucketParser::apply, bucketParser::apply);
objectParser.declareLong((parsedTerms, value) -> parsedTerms.subsetSize = value , CommonFields.DOC_COUNT);
}
public abstract static class ParsedBucket extends ParsedMultiBucketAggregation.ParsedBucket implements SignificantTerms.Bucket {
protected long subsetDf;
protected long supersetDf;
protected double score;
@Override
public long getDocCount() {
return getSubsetDf();
}
@Override
public long getSubsetDf() {
return subsetDf;
}
@Override
public long getSupersetDf() {
return supersetDf;
}
@Override
public double getSignificanceScore() {
return score;
}
@Override
public long getSupersetSize() {
throw new UnsupportedOperationException();
}
@Override
public long getSubsetSize() {
throw new UnsupportedOperationException();
}
@Override
public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
keyToXContent(builder);
builder.field(CommonFields.DOC_COUNT.getPreferredName(), getDocCount());
builder.field(InternalSignificantTerms.SCORE, getSignificanceScore());
builder.field(InternalSignificantTerms.BG_COUNT, getSupersetDf());
getAggregations().toXContentInternal(builder, params);
builder.endObject();
return builder;
}
protected abstract XContentBuilder keyToXContent(XContentBuilder builder) throws IOException;
static <B extends ParsedBucket> B parseSignificantTermsBucketXContent(final XContentParser parser, final B bucket,
final CheckedBiConsumer<XContentParser, B, IOException> keyConsumer) throws IOException {
final List<Aggregation> aggregations = new ArrayList<>();
XContentParser.Token token;
String currentFieldName = parser.currentName();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (CommonFields.KEY_AS_STRING.getPreferredName().equals(currentFieldName)) {
bucket.setKeyAsString(parser.text());
} else if (CommonFields.KEY.getPreferredName().equals(currentFieldName)) {
keyConsumer.accept(parser, bucket);
} else if (CommonFields.DOC_COUNT.getPreferredName().equals(currentFieldName)) {
long value = parser.longValue();
bucket.subsetDf = value;
bucket.setDocCount(value);
} else if (InternalSignificantTerms.SCORE.equals(currentFieldName)) {
bucket.score = parser.longValue();
} else if (InternalSignificantTerms.BG_COUNT.equals(currentFieldName)) {
bucket.supersetDf = parser.longValue();
}
} else if (token == XContentParser.Token.START_OBJECT) {
aggregations.add(XContentParserUtils.parseTypedKeysObject(parser, Aggregation.TYPED_KEYS_DELIMITER, Aggregation.class));
}
}
bucket.setAggregations(new Aggregations(aggregations));
return bucket;
}
}
}

View File

@ -40,6 +40,8 @@ import org.elasticsearch.search.aggregations.bucket.range.InternalRangeTests;
import org.elasticsearch.search.aggregations.bucket.range.date.InternalDateRangeTests; import org.elasticsearch.search.aggregations.bucket.range.date.InternalDateRangeTests;
import org.elasticsearch.search.aggregations.bucket.range.geodistance.InternalGeoDistanceTests; import org.elasticsearch.search.aggregations.bucket.range.geodistance.InternalGeoDistanceTests;
import org.elasticsearch.search.aggregations.bucket.sampler.InternalSamplerTests; import org.elasticsearch.search.aggregations.bucket.sampler.InternalSamplerTests;
import org.elasticsearch.search.aggregations.bucket.significant.SignificantLongTermsTests;
import org.elasticsearch.search.aggregations.bucket.significant.SignificantStringTermsTests;
import org.elasticsearch.search.aggregations.bucket.terms.DoubleTermsTests; import org.elasticsearch.search.aggregations.bucket.terms.DoubleTermsTests;
import org.elasticsearch.search.aggregations.bucket.terms.LongTermsTests; import org.elasticsearch.search.aggregations.bucket.terms.LongTermsTests;
import org.elasticsearch.search.aggregations.bucket.terms.StringTermsTests; import org.elasticsearch.search.aggregations.bucket.terms.StringTermsTests;
@ -126,6 +128,8 @@ public class AggregationsTests extends ESTestCase {
aggsTests.add(new InternalGeoDistanceTests()); aggsTests.add(new InternalGeoDistanceTests());
aggsTests.add(new InternalFiltersTests()); aggsTests.add(new InternalFiltersTests());
aggsTests.add(new InternalAdjacencyMatrixTests()); aggsTests.add(new InternalAdjacencyMatrixTests());
aggsTests.add(new SignificantLongTermsTests());
aggsTests.add(new SignificantStringTermsTests());
return Collections.unmodifiableList(aggsTests); return Collections.unmodifiableList(aggsTests);
} }

View File

@ -67,28 +67,22 @@ public abstract class InternalMultiBucketAggregationTestCase<T extends InternalA
@Override @Override
protected final void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) { protected final void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) {
assertMultiBucketsAggregation(aggregation, parsedAggregation, false); assertMultiBucketsAggregations(aggregation, parsedAggregation, false);
} }
public void testIterators() throws IOException { public void testIterators() throws IOException {
final T aggregation = createTestInstance(); final T aggregation = createTestInstance();
assertMultiBucketsAggregation(aggregation, parseAndAssert(aggregation, false), true); assertMultiBucketsAggregations(aggregation, parseAndAssert(aggregation, false), true);
} }
private void assertMultiBucketsAggregation(Aggregation expected, Aggregation actual, boolean checkOrder) { private void assertMultiBucketsAggregations(Aggregation expected, Aggregation actual, boolean checkOrder) {
assertTrue(expected instanceof MultiBucketsAggregation); assertTrue(expected instanceof MultiBucketsAggregation);
MultiBucketsAggregation expectedMultiBucketsAggregation = (MultiBucketsAggregation) expected; MultiBucketsAggregation expectedMultiBucketsAggregation = (MultiBucketsAggregation) expected;
assertTrue(actual instanceof MultiBucketsAggregation); assertTrue(actual instanceof MultiBucketsAggregation);
MultiBucketsAggregation actualMultiBucketsAggregation = (MultiBucketsAggregation) actual; MultiBucketsAggregation actualMultiBucketsAggregation = (MultiBucketsAggregation) actual;
Class<? extends ParsedMultiBucketAggregation> parsedClass = implementationClass(); assertMultiBucketsAggregation(expectedMultiBucketsAggregation, actualMultiBucketsAggregation, checkOrder);
assertTrue(parsedClass != null && parsedClass.isInstance(actual));
assertTrue(expected instanceof InternalAggregation && actual instanceof ParsedAggregation);
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.getMetaData(), actual.getMetaData());
assertEquals(((InternalAggregation) expected).getType(), ((ParsedAggregation) actual).getType());
List<? extends MultiBucketsAggregation.Bucket> expectedBuckets = expectedMultiBucketsAggregation.getBuckets(); List<? extends MultiBucketsAggregation.Bucket> expectedBuckets = expectedMultiBucketsAggregation.getBuckets();
List<? extends MultiBucketsAggregation.Bucket> actualBuckets = actualMultiBucketsAggregation.getBuckets(); List<? extends MultiBucketsAggregation.Bucket> actualBuckets = actualMultiBucketsAggregation.getBuckets();
@ -117,6 +111,17 @@ public abstract class InternalMultiBucketAggregationTestCase<T extends InternalA
} }
} }
protected void assertMultiBucketsAggregation(MultiBucketsAggregation expected, MultiBucketsAggregation actual, boolean checkOrder) {
Class<? extends ParsedMultiBucketAggregation> parsedClass = implementationClass();
assertNotNull("Parsed aggregation class must not be null", parsedClass);
assertTrue(parsedClass.isInstance(actual));
assertTrue(expected instanceof InternalAggregation);
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.getMetaData(), actual.getMetaData());
assertEquals(((InternalAggregation) expected).getType(), ((ParsedAggregation) actual).getType());
}
protected void assertBucket(MultiBucketsAggregation.Bucket expected, MultiBucketsAggregation.Bucket actual, boolean checkOrder) { protected void assertBucket(MultiBucketsAggregation.Bucket expected, MultiBucketsAggregation.Bucket actual, boolean checkOrder) {
assertTrue(expected instanceof InternalMultiBucketAggregation.InternalBucket); assertTrue(expected instanceof InternalMultiBucketAggregation.InternalBucket);
assertTrue(actual instanceof ParsedMultiBucketAggregation.ParsedBucket); assertTrue(actual instanceof ParsedMultiBucketAggregation.ParsedBucket);
@ -136,13 +141,13 @@ public abstract class InternalMultiBucketAggregationTestCase<T extends InternalA
while (expectedIt.hasNext()) { while (expectedIt.hasNext()) {
Aggregation expectedAggregation = expectedIt.next(); Aggregation expectedAggregation = expectedIt.next();
Aggregation actualAggregation = actualIt.next(); Aggregation actualAggregation = actualIt.next();
assertMultiBucketsAggregation(expectedAggregation, actualAggregation, true); assertMultiBucketsAggregations(expectedAggregation, actualAggregation, true);
} }
} else { } else {
for (Aggregation expectedAggregation : expectedAggregations) { for (Aggregation expectedAggregation : expectedAggregations) {
Aggregation actualAggregation = actualAggregations.get(expectedAggregation.getName()); Aggregation actualAggregation = actualAggregations.get(expectedAggregation.getName());
assertNotNull(actualAggregation); assertNotNull(actualAggregation);
assertMultiBucketsAggregation(expectedAggregation, actualAggregation, false); assertMultiBucketsAggregations(expectedAggregation, actualAggregation, false);
} }
} }
} }

View File

@ -19,8 +19,9 @@
package org.elasticsearch.search.aggregations.bucket.significant; package org.elasticsearch.search.aggregations.bucket.significant;
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregationTestCase;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.test.InternalAggregationTestCase;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -30,7 +31,7 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
public abstract class InternalSignificantTermsTestCase extends InternalAggregationTestCase<InternalSignificantTerms<?, ?>> { public abstract class InternalSignificantTermsTestCase extends InternalMultiBucketAggregationTestCase<InternalSignificantTerms<?, ?>> {
@Override @Override
protected InternalSignificantTerms createUnmappedInstance(String name, protected InternalSignificantTerms createUnmappedInstance(String name,
@ -61,6 +62,41 @@ public abstract class InternalSignificantTermsTestCase extends InternalAggregati
} }
} }
@Override
protected void assertMultiBucketsAggregation(MultiBucketsAggregation expected, MultiBucketsAggregation actual, boolean checkOrder) {
super.assertMultiBucketsAggregation(expected, actual, checkOrder);
assertTrue(expected instanceof InternalSignificantTerms);
assertTrue(actual instanceof ParsedSignificantTerms);
InternalSignificantTerms expectedSigTerms = (InternalSignificantTerms) expected;
ParsedSignificantTerms actualSigTerms = (ParsedSignificantTerms) actual;
assertEquals(expectedSigTerms.getSubsetSize(), actualSigTerms.getSubsetSize());
for (SignificantTerms.Bucket bucket : (SignificantTerms) expected) {
String key = bucket.getKeyAsString();
assertBucket(expectedSigTerms.getBucketByKey(key), actualSigTerms.getBucketByKey(key), checkOrder);
}
}
@Override
protected void assertBucket(MultiBucketsAggregation.Bucket expected, MultiBucketsAggregation.Bucket actual, boolean checkOrder) {
super.assertBucket(expected, actual, checkOrder);
assertTrue(expected instanceof InternalSignificantTerms.Bucket);
assertTrue(actual instanceof ParsedSignificantTerms.ParsedBucket);
SignificantTerms.Bucket expectedSigTerm = (SignificantTerms.Bucket) expected;
SignificantTerms.Bucket actualSigTerm = (SignificantTerms.Bucket) actual;
assertEquals(expectedSigTerm.getSignificanceScore(), actualSigTerm.getSignificanceScore(), 0.0);
assertEquals(expectedSigTerm.getSubsetDf(), actualSigTerm.getSubsetDf());
assertEquals(expectedSigTerm.getSupersetDf(), actualSigTerm.getSupersetDf());
expectThrows(UnsupportedOperationException.class, actualSigTerm::getSubsetSize);
expectThrows(UnsupportedOperationException.class, actualSigTerm::getSupersetSize);
}
private static Map<Object, Long> toCounts(Stream<? extends SignificantTerms.Bucket> buckets, private static Map<Object, Long> toCounts(Stream<? extends SignificantTerms.Bucket> buckets,
Function<SignificantTerms.Bucket, Long> fn) { Function<SignificantTerms.Bucket, Long> fn) {
return buckets.collect(Collectors.toMap(SignificantTerms.Bucket::getKey, fn, Long::sum)); return buckets.collect(Collectors.toMap(SignificantTerms.Bucket::getKey, fn, Long::sum));

View File

@ -21,6 +21,8 @@ package org.elasticsearch.search.aggregations.bucket.significant;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.ParsedMultiBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.ChiSquare; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.ChiSquare;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.GND; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.GND;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.JLHScore; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.JLHScore;
@ -35,22 +37,24 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.elasticsearch.search.aggregations.InternalAggregations.EMPTY;
public class SignificantLongTermsTests extends InternalSignificantTermsTestCase { public class SignificantLongTermsTests extends InternalSignificantTermsTestCase {
private SignificanceHeuristic significanceHeuristic; private SignificanceHeuristic significanceHeuristic;
private DocValueFormat format;
@Override
@Before @Before
public void setUpSignificanceHeuristic() { public void setUp() throws Exception {
super.setUp();
significanceHeuristic = randomSignificanceHeuristic(); significanceHeuristic = randomSignificanceHeuristic();
format = randomNumericDocValueFormat();
} }
@Override @Override
protected InternalSignificantTerms createTestInstance(String name, protected InternalSignificantTerms createTestInstance(String name,
List<PipelineAggregator> pipelineAggregators, List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData) { Map<String, Object> metaData,
DocValueFormat format = DocValueFormat.RAW; InternalAggregations aggregations) {
int requiredSize = randomIntBetween(1, 5); int requiredSize = randomIntBetween(1, 5);
int shardSize = requiredSize + 2; int shardSize = requiredSize + 2;
final int numBuckets = randomInt(shardSize); final int numBuckets = randomInt(shardSize);
@ -70,7 +74,7 @@ public class SignificantLongTermsTests extends InternalSignificantTermsTestCase
globalSubsetSize += subsetDf; globalSubsetSize += subsetDf;
globalSupersetSize += supersetSize; globalSupersetSize += supersetSize;
buckets.add(new SignificantLongTerms.Bucket(subsetDf, subsetDf, supersetDf, supersetSize, term, EMPTY, format)); buckets.add(new SignificantLongTerms.Bucket(subsetDf, subsetDf, supersetDf, supersetSize, term, aggregations, format));
} }
return new SignificantLongTerms(name, requiredSize, 1L, pipelineAggregators, metaData, format, globalSubsetSize, return new SignificantLongTerms(name, requiredSize, 1L, pipelineAggregators, metaData, format, globalSubsetSize,
globalSupersetSize, significanceHeuristic, buckets); globalSupersetSize, significanceHeuristic, buckets);
@ -81,6 +85,11 @@ public class SignificantLongTermsTests extends InternalSignificantTermsTestCase
return SignificantLongTerms::new; return SignificantLongTerms::new;
} }
@Override
protected Class<? extends ParsedMultiBucketAggregation> implementationClass() {
return ParsedSignificantLongTerms.class;
}
private static SignificanceHeuristic randomSignificanceHeuristic() { private static SignificanceHeuristic randomSignificanceHeuristic() {
return randomFrom( return randomFrom(
new JLHScore(), new JLHScore(),

View File

@ -22,6 +22,8 @@ package org.elasticsearch.search.aggregations.bucket.significant;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.ParsedMultiBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.ChiSquare; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.ChiSquare;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.GND; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.GND;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.JLHScore; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.JLHScore;
@ -36,21 +38,22 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.elasticsearch.search.aggregations.InternalAggregations.EMPTY;
public class SignificantStringTermsTests extends InternalSignificantTermsTestCase { public class SignificantStringTermsTests extends InternalSignificantTermsTestCase {
private SignificanceHeuristic significanceHeuristic; private SignificanceHeuristic significanceHeuristic;
@Override
@Before @Before
public void setUpSignificanceHeuristic() { public void setUp() throws Exception {
super.setUp();
significanceHeuristic = randomSignificanceHeuristic(); significanceHeuristic = randomSignificanceHeuristic();
} }
@Override @Override
protected InternalSignificantTerms createTestInstance(String name, protected InternalSignificantTerms createTestInstance(String name,
List<PipelineAggregator> pipelineAggregators, List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData) { Map<String, Object> metaData,
InternalAggregations aggregations) {
DocValueFormat format = DocValueFormat.RAW; DocValueFormat format = DocValueFormat.RAW;
int requiredSize = randomIntBetween(1, 5); int requiredSize = randomIntBetween(1, 5);
int shardSize = requiredSize + 2; int shardSize = requiredSize + 2;
@ -71,7 +74,7 @@ public class SignificantStringTermsTests extends InternalSignificantTermsTestCas
globalSubsetSize += subsetDf; globalSubsetSize += subsetDf;
globalSupersetSize += supersetSize; globalSupersetSize += supersetSize;
buckets.add(new SignificantStringTerms.Bucket(term, subsetDf, subsetDf, supersetDf, supersetSize, EMPTY, format)); buckets.add(new SignificantStringTerms.Bucket(term, subsetDf, subsetDf, supersetDf, supersetSize, aggregations, format));
} }
return new SignificantStringTerms(name, requiredSize, 1L, pipelineAggregators, metaData, format, globalSubsetSize, return new SignificantStringTerms(name, requiredSize, 1L, pipelineAggregators, metaData, format, globalSubsetSize,
globalSupersetSize, significanceHeuristic, buckets); globalSupersetSize, significanceHeuristic, buckets);
@ -82,6 +85,11 @@ public class SignificantStringTermsTests extends InternalSignificantTermsTestCas
return SignificantStringTerms::new; return SignificantStringTerms::new;
} }
@Override
protected Class<? extends ParsedMultiBucketAggregation> implementationClass() {
return ParsedSignificantStringTerms.class;
}
private static SignificanceHeuristic randomSignificanceHeuristic() { private static SignificanceHeuristic randomSignificanceHeuristic() {
return randomFrom( return randomFrom(
new JLHScore(), new JLHScore(),

View File

@ -66,6 +66,10 @@ import org.elasticsearch.search.aggregations.bucket.range.geodistance.GeoDistanc
import org.elasticsearch.search.aggregations.bucket.range.geodistance.ParsedGeoDistance; import org.elasticsearch.search.aggregations.bucket.range.geodistance.ParsedGeoDistance;
import org.elasticsearch.search.aggregations.bucket.sampler.InternalSampler; import org.elasticsearch.search.aggregations.bucket.sampler.InternalSampler;
import org.elasticsearch.search.aggregations.bucket.sampler.ParsedSampler; import org.elasticsearch.search.aggregations.bucket.sampler.ParsedSampler;
import org.elasticsearch.search.aggregations.bucket.significant.ParsedSignificantLongTerms;
import org.elasticsearch.search.aggregations.bucket.significant.ParsedSignificantStringTerms;
import org.elasticsearch.search.aggregations.bucket.significant.SignificantLongTerms;
import org.elasticsearch.search.aggregations.bucket.significant.SignificantStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.DoubleTerms; import org.elasticsearch.search.aggregations.bucket.terms.DoubleTerms;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms; import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedDoubleTerms; import org.elasticsearch.search.aggregations.bucket.terms.ParsedDoubleTerms;
@ -176,6 +180,8 @@ public abstract class InternalAggregationTestCase<T extends InternalAggregation>
map.put(GeoDistanceAggregationBuilder.NAME, (p, c) -> ParsedGeoDistance.fromXContent(p, (String) c)); map.put(GeoDistanceAggregationBuilder.NAME, (p, c) -> ParsedGeoDistance.fromXContent(p, (String) c));
map.put(FiltersAggregationBuilder.NAME, (p, c) -> ParsedFilters.fromXContent(p, (String) c)); map.put(FiltersAggregationBuilder.NAME, (p, c) -> ParsedFilters.fromXContent(p, (String) c));
map.put(AdjacencyMatrixAggregationBuilder.NAME, (p, c) -> ParsedAdjacencyMatrix.fromXContent(p, (String) c)); map.put(AdjacencyMatrixAggregationBuilder.NAME, (p, c) -> ParsedAdjacencyMatrix.fromXContent(p, (String) c));
map.put(SignificantLongTerms.NAME, (p, c) -> ParsedSignificantLongTerms.fromXContent(p, (String) c));
map.put(SignificantStringTerms.NAME, (p, c) -> ParsedSignificantStringTerms.fromXContent(p, (String) c));
namedXContents = map.entrySet().stream() namedXContents = map.entrySet().stream()
.map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue()))