[Tests] Add tests for CompletionSuggestionBuilder#build() (#25575)
This adds a unit test that checks the CompletionSuggestionContext that is the output of CompletionSuggestionBuilder#build.
This commit is contained in:
parent
5762bce4b8
commit
0e8d7582ec
|
@ -24,10 +24,12 @@ import org.elasticsearch.common.bytes.BytesReference;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.unit.Fuzziness;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.mapper.CompletionFieldMapper;
|
||||
|
@ -52,6 +54,7 @@ import java.util.Objects;
|
|||
* indexing.
|
||||
*/
|
||||
public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSuggestionBuilder> {
|
||||
private static final XContentType CONTEXT_BYTES_XCONTENT_TYPE = XContentType.JSON;
|
||||
static final String SUGGESTION_NAME = "completion";
|
||||
static final ParseField CONTEXTS_FIELD = new ParseField("contexts", "context");
|
||||
|
||||
|
@ -86,7 +89,7 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
|
|||
PARSER.declareInt(CompletionSuggestionBuilder.InnerBuilder::shardSize, SHARDSIZE_FIELD);
|
||||
PARSER.declareField((p, v, c) -> {
|
||||
// Copy the current structure. We will parse, once the mapping is provided
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(CONTEXT_BYTES_XCONTENT_TYPE);
|
||||
builder.copyCurrentStructure(p);
|
||||
v.contextBytes = builder.bytes();
|
||||
p.skipChildren();
|
||||
|
@ -186,7 +189,7 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
|
|||
public CompletionSuggestionBuilder contexts(Map<String, List<? extends ToXContent>> queryContexts) {
|
||||
Objects.requireNonNull(queryContexts, "contexts must not be null");
|
||||
try {
|
||||
XContentBuilder contentBuilder = XContentFactory.jsonBuilder();
|
||||
XContentBuilder contentBuilder = XContentFactory.contentBuilder(CONTEXT_BYTES_XCONTENT_TYPE);
|
||||
contentBuilder.startObject();
|
||||
for (Map.Entry<String, List<? extends ToXContent>> contextEntry : queryContexts.entrySet()) {
|
||||
contentBuilder.startArray(contextEntry.getKey());
|
||||
|
@ -255,33 +258,16 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
|
|||
suggestionContext.setFuzzyOptions(fuzzyOptions);
|
||||
suggestionContext.setRegexOptions(regexOptions);
|
||||
MappedFieldType mappedFieldType = mapperService.fullName(suggestionContext.getField());
|
||||
if (mappedFieldType == null ||
|
||||
mappedFieldType instanceof CompletionFieldMapper.CompletionFieldType == false) {
|
||||
if (mappedFieldType == null || mappedFieldType instanceof CompletionFieldMapper.CompletionFieldType == false) {
|
||||
throw new IllegalArgumentException("Field [" + suggestionContext.getField() + "] is not a completion suggest field");
|
||||
}
|
||||
if (mappedFieldType instanceof CompletionFieldMapper.CompletionFieldType) {
|
||||
CompletionFieldMapper.CompletionFieldType type = (CompletionFieldMapper.CompletionFieldType) mappedFieldType;
|
||||
suggestionContext.setFieldType(type);
|
||||
if (type.hasContextMappings() && contextBytes != null) {
|
||||
try (XContentParser contextParser = XContentFactory.xContent(contextBytes).createParser(context.getXContentRegistry(),
|
||||
contextBytes)) {
|
||||
if (type.hasContextMappings() && contextParser != null) {
|
||||
ContextMappings contextMappings = type.getContextMappings();
|
||||
contextParser.nextToken();
|
||||
Map<String, List<ContextMapping.InternalQueryContext>> queryContexts = new HashMap<>(contextMappings.size());
|
||||
assert contextParser.currentToken() == XContentParser.Token.START_OBJECT;
|
||||
XContentParser.Token currentToken;
|
||||
String currentFieldName;
|
||||
while ((currentToken = contextParser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (currentToken == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = contextParser.currentName();
|
||||
final ContextMapping mapping = contextMappings.get(currentFieldName);
|
||||
queryContexts.put(currentFieldName, mapping.parseQueryContext(contextParser));
|
||||
}
|
||||
}
|
||||
suggestionContext.setQueryContexts(queryContexts);
|
||||
}
|
||||
}
|
||||
Map<String, List<ContextMapping.InternalQueryContext>> queryContexts = parseContextBytes(contextBytes,
|
||||
context.getXContentRegistry(), type.getContextMappings());
|
||||
suggestionContext.setQueryContexts(queryContexts);
|
||||
} else if (contextBytes != null) {
|
||||
throw new IllegalArgumentException("suggester [" + type.name() + "] doesn't expect any context");
|
||||
}
|
||||
|
@ -290,6 +276,25 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
|
|||
return suggestionContext;
|
||||
}
|
||||
|
||||
static Map<String, List<ContextMapping.InternalQueryContext>> parseContextBytes(BytesReference contextBytes,
|
||||
NamedXContentRegistry xContentRegistry, ContextMappings contextMappings) throws IOException {
|
||||
try (XContentParser contextParser = XContentHelper.createParser(xContentRegistry, contextBytes, CONTEXT_BYTES_XCONTENT_TYPE)) {
|
||||
contextParser.nextToken();
|
||||
Map<String, List<ContextMapping.InternalQueryContext>> queryContexts = new HashMap<>(contextMappings.size());
|
||||
assert contextParser.currentToken() == XContentParser.Token.START_OBJECT;
|
||||
XContentParser.Token currentToken;
|
||||
String currentFieldName;
|
||||
while ((currentToken = contextParser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (currentToken == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = contextParser.currentName();
|
||||
final ContextMapping<?> mapping = contextMappings.get(currentFieldName);
|
||||
queryContexts.put(currentFieldName, mapping.parseQueryContext(contextParser));
|
||||
}
|
||||
}
|
||||
return queryContexts;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteableName() {
|
||||
return SUGGESTION_NAME;
|
||||
|
|
|
@ -201,14 +201,14 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui
|
|||
} else {
|
||||
assertEquals("mapperServiceSearchAnalyzer", ((NamedAnalyzer) suggestionContext.getAnalyzer()).name());
|
||||
}
|
||||
assertSuggester(suggestionBuilder, suggestionContext);
|
||||
assertSuggestionContext(suggestionBuilder, suggestionContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* put suggester dependent assertions in the sub type test
|
||||
* put implementation dependent assertions in the sub-type test
|
||||
*/
|
||||
protected abstract void assertSuggester(SB builder, SuggestionContext context);
|
||||
protected abstract void assertSuggestionContext(SB builder, SuggestionContext context) throws IOException;
|
||||
|
||||
protected MappedFieldType mockFieldType() {
|
||||
return mock(MappedFieldType.class);
|
||||
|
|
|
@ -29,17 +29,19 @@ import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContex
|
|||
import org.elasticsearch.search.suggest.completion.context.CategoryQueryContext;
|
||||
import org.elasticsearch.search.suggest.completion.context.ContextBuilder;
|
||||
import org.elasticsearch.search.suggest.completion.context.ContextMapping;
|
||||
import org.elasticsearch.search.suggest.completion.context.ContextMapping.InternalQueryContext;
|
||||
import org.elasticsearch.search.suggest.completion.context.ContextMappings;
|
||||
import org.elasticsearch.search.suggest.completion.context.GeoQueryContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTestCase<CompletionSuggestionBuilder> {
|
||||
|
||||
private static final String[] SHUFFLE_PROTECTED_FIELDS = new String[] { CompletionSuggestionBuilder.CONTEXTS_FIELD.getPreferredName() };
|
||||
|
@ -54,7 +56,7 @@ public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTe
|
|||
}
|
||||
|
||||
public static CompletionSuggestionBuilder randomCompletionSuggestionBuilder() {
|
||||
// lazy initialization of context names and mappings, cannot be done in init method because other test
|
||||
// lazy initialization of context names and mappings, cannot be done in some init method because other test
|
||||
// also create random CompletionSuggestionBuilder instances
|
||||
if (categoryContextName == null) {
|
||||
categoryContextName = randomAlphaOfLength(10);
|
||||
|
@ -62,9 +64,9 @@ public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTe
|
|||
if (geoQueryContextName == null) {
|
||||
geoQueryContextName = randomAlphaOfLength(10);
|
||||
}
|
||||
if (contextMappings == null) {
|
||||
contextMappings = Arrays.asList(new ContextMapping[] { ContextBuilder.category(categoryContextName).build(),
|
||||
ContextBuilder.geo(geoQueryContextName).build() });
|
||||
if (contextMappings.isEmpty()) {
|
||||
contextMappings.add(ContextBuilder.category(categoryContextName).build());
|
||||
contextMappings.add(ContextBuilder.geo(geoQueryContextName).build());
|
||||
}
|
||||
// lazy initialization of context names and mappings, cannot be done in some init method because other test
|
||||
// also create random CompletionSuggestionBuilder instances
|
||||
|
@ -165,6 +167,20 @@ public class CompletionSuggesterBuilderTests extends AbstractSuggestionBuilderTe
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void assertSuggester(CompletionSuggestionBuilder builder, SuggestionContext context) {
|
||||
protected void assertSuggestionContext(CompletionSuggestionBuilder builder, SuggestionContext context) throws IOException {
|
||||
assertThat(context, instanceOf(CompletionSuggestionContext.class));
|
||||
assertThat(context.getSuggester(), instanceOf(CompletionSuggester.class));
|
||||
CompletionSuggestionContext completionSuggestionCtx = (CompletionSuggestionContext) context;
|
||||
assertThat(completionSuggestionCtx.getFieldType(), instanceOf(CompletionFieldType.class) );
|
||||
assertEquals(builder.fuzzyOptions, completionSuggestionCtx.getFuzzyOptions());
|
||||
Map<String, List<InternalQueryContext>> parsedContextBytes;
|
||||
parsedContextBytes = CompletionSuggestionBuilder.parseContextBytes(builder.contextBytes, xContentRegistry(),
|
||||
new ContextMappings(contextMappings));
|
||||
Map<String, List<InternalQueryContext>> queryContexts = completionSuggestionCtx.getQueryContexts();
|
||||
assertEquals(parsedContextBytes.keySet(), queryContexts.keySet());
|
||||
for (String contextName : queryContexts.keySet()) {
|
||||
assertEquals(parsedContextBytes.get(contextName), queryContexts.get(contextName));
|
||||
}
|
||||
assertEquals(builder.regexOptions, completionSuggestionCtx.getRegexOptions());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ public class PhraseSuggestionBuilderTests extends AbstractSuggestionBuilderTestC
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void assertSuggester(PhraseSuggestionBuilder builder, SuggestionContext context) {
|
||||
protected void assertSuggestionContext(PhraseSuggestionBuilder builder, SuggestionContext context) {
|
||||
assertThat(context, instanceOf(PhraseSuggestionContext.class));
|
||||
assertThat(context.getSuggester(), instanceOf(PhraseSuggester.class));
|
||||
PhraseSuggestionContext phraseSuggesterCtx = (PhraseSuggestionContext) context;
|
||||
|
|
|
@ -227,7 +227,7 @@ public class TermSuggestionBuilderTests extends AbstractSuggestionBuilderTestCas
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void assertSuggester(TermSuggestionBuilder builder, SuggestionContext context) {
|
||||
protected void assertSuggestionContext(TermSuggestionBuilder builder, SuggestionContext context) {
|
||||
assertThat(context, instanceOf(TermSuggestionContext.class));
|
||||
assertThat(context.getSuggester(), instanceOf(TermSuggester.class));
|
||||
TermSuggestionContext termSuggesterCtx = (TermSuggestionContext) context;
|
||||
|
|
Loading…
Reference in New Issue