Use ObjectParser in ScoreSortBuilder and FieldSortBuilder

This commit is contained in:
Christoph Büscher 2016-10-12 19:04:37 +02:00
parent 4fbe1a8819
commit 1b78618106
4 changed files with 29 additions and 88 deletions

View File

@ -24,8 +24,9 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested; import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
import org.elasticsearch.index.fielddata.IndexNumericFieldData; import org.elasticsearch.index.fielddata.IndexNumericFieldData;
@ -39,7 +40,6 @@ import org.elasticsearch.search.MultiValueMode;
import java.io.IOException; import java.io.IOException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
/** /**
* A sort builder to sort based on a document field. * A sort builder to sort based on a document field.
@ -327,67 +327,24 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> {
* in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument * in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument
*/ */
public static FieldSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException { public static FieldSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException {
XContentParser parser = context.parser(); return PARSER.parse(context.parser(), new FieldSortBuilder(fieldName), context);
}
Optional<QueryBuilder> nestedFilter = Optional.empty(); private static ObjectParser<FieldSortBuilder, QueryParseContext> PARSER = new ObjectParser<>(NAME);
String nestedPath = null;
Object missing = null;
SortOrder order = null;
SortMode sortMode = null;
String unmappedType = null;
String currentFieldName = null; static {
XContentParser.Token token; PARSER.declareField(FieldSortBuilder::missing, p -> p.objectText(), MISSING, ValueType.VALUE);
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { PARSER.declareString(FieldSortBuilder::setNestedPath , NESTED_PATH);
if (token == XContentParser.Token.FIELD_NAME) { PARSER.declareString(FieldSortBuilder::unmappedType , UNMAPPED_TYPE);
currentFieldName = parser.currentName(); PARSER.declareField(FieldSortBuilder::order, p -> SortOrder.fromString(p.text()), ORDER_FIELD, ValueType.STRING);
} else if (token == XContentParser.Token.START_OBJECT) { PARSER.declareField(FieldSortBuilder::sortMode, p -> SortMode.fromString(p.text()), SORT_MODE, ValueType.STRING);
if (context.getParseFieldMatcher().match(currentFieldName, NESTED_FILTER)) { PARSER.declareObject(FieldSortBuilder::setNestedFilter, (p, c) -> {
nestedFilter = context.parseInnerQueryBuilder(); try {
} else { QueryBuilder builder = c.parseInnerQueryBuilder().orElseThrow(
throw new ParsingException(parser.getTokenLocation(), "Expected " + NESTED_FILTER.getPreferredName() + " element."); () -> new ParsingException(p.getTokenLocation(), "Expected " + NESTED_FILTER.getPreferredName() + " element."));
} return builder;
} else if (token.isValue()) { } catch (Exception e) {
if (context.getParseFieldMatcher().match(currentFieldName, NESTED_PATH)) { throw new ParsingException(p.getTokenLocation(), "Expected " + NESTED_FILTER.getPreferredName() + " element.", e);
nestedPath = parser.text(); }}, NESTED_FILTER);
} else if (context.getParseFieldMatcher().match(currentFieldName, MISSING)) {
missing = parser.objectText();
} else if (context.getParseFieldMatcher().match(currentFieldName, ORDER)) {
String sortOrder = parser.text();
if ("asc".equals(sortOrder)) {
order = SortOrder.ASC;
} else if ("desc".equals(sortOrder)) {
order = SortOrder.DESC;
} else {
throw new ParsingException(parser.getTokenLocation(), "Sort order [{}] not supported.", sortOrder);
}
} else if (context.getParseFieldMatcher().match(currentFieldName, SORT_MODE)) {
sortMode = SortMode.fromString(parser.text());
} else if (context.getParseFieldMatcher().match(currentFieldName, UNMAPPED_TYPE)) {
unmappedType = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "Option [{}] not supported.", currentFieldName);
}
}
}
FieldSortBuilder builder = new FieldSortBuilder(fieldName);
nestedFilter.ifPresent(builder::setNestedFilter);
if (nestedPath != null) {
builder.setNestedPath(nestedPath);
}
if (missing != null) {
builder.missing(missing);
}
if (order != null) {
builder.order(order);
}
if (sortMode != null) {
builder.sortMode(sortMode);
}
if (unmappedType != null) {
builder.unmappedType(unmappedType);
}
return builder;
} }
} }

View File

@ -21,12 +21,11 @@ package org.elasticsearch.search.sort;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.DocValueFormat;
@ -86,26 +85,13 @@ public class ScoreSortBuilder extends SortBuilder<ScoreSortBuilder> {
* in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument * in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument
*/ */
public static ScoreSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException { public static ScoreSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException {
XContentParser parser = context.parser(); return PARSER.apply(context.parser(), context);
ParseFieldMatcher matcher = context.getParseFieldMatcher(); }
XContentParser.Token token; private static ObjectParser<ScoreSortBuilder, QueryParseContext> PARSER = new ObjectParser<>(NAME, ScoreSortBuilder::new);
String currentName = parser.currentName();
ScoreSortBuilder result = new ScoreSortBuilder(); static {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { PARSER.declareField(ScoreSortBuilder::order, p -> SortOrder.fromString(p.text()), ORDER_FIELD, ValueType.STRING);
if (token == XContentParser.Token.FIELD_NAME) {
currentName = parser.currentName();
} else if (token.isValue()) {
if (matcher.match(currentName, ORDER_FIELD)) {
result.order(SortOrder.fromString(parser.text()));
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + NAME + "] failed to parse field [" + currentName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + NAME + "] unexpected token [" + token + "]");
}
}
return result;
} }
@Override @Override

View File

@ -21,7 +21,6 @@ package org.elasticsearch.search.sort;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryParseContext;
@ -140,7 +139,7 @@ public class FieldSortBuilderTests extends AbstractSortTestCase<FieldSortBuilder
try { try {
FieldSortBuilder.fromXContent(context, ""); FieldSortBuilder.fromXContent(context, "");
fail("adding reverse sorting option should fail with an exception"); fail("adding reverse sorting option should fail with an exception");
} catch (ParsingException e) { } catch (IllegalArgumentException e) {
// all good // all good
} }
} }

View File

@ -22,7 +22,6 @@ package org.elasticsearch.search.sort;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryParseContext;
@ -93,7 +92,7 @@ public class ScoreSortBuilderTests extends AbstractSortTestCase<ScoreSortBuilder
try { try {
ScoreSortBuilder.fromXContent(context, "_score"); ScoreSortBuilder.fromXContent(context, "_score");
fail("adding reverse sorting option should fail with an exception"); fail("adding reverse sorting option should fail with an exception");
} catch (ParsingException e) { } catch (IllegalArgumentException e) {
// all good // all good
} }
} }