Moves SortParser:parse(...) to only require QueryShardContext

This removes the need for accessing the SearchContext when parsing Sort elements
to queries. After applying the patch only a QueryShardContext is needed.

Relates to #15178
This commit is contained in:
Isabel Drost-Fromm 2016-03-08 10:28:26 +01:00
parent c9e1ccf610
commit a4b5fbedb8
8 changed files with 48 additions and 39 deletions

View File

@ -20,10 +20,14 @@
package org.elasticsearch.index.fielddata; package org.elasticsearch.index.fielddata;
import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.FieldComparatorSource; import org.apache.lucene.search.FieldComparatorSource;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.apache.lucene.search.Weight; import org.apache.lucene.search.Weight;
@ -122,11 +126,11 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
public static class Nested { public static class Nested {
private final BitSetProducer rootFilter; private final BitSetProducer rootFilter;
private final Weight innerFilter; private final Query innerQuery;
public Nested(BitSetProducer rootFilter, Weight innerFilter) { public Nested(BitSetProducer rootFilter, Query innerQuery) {
this.rootFilter = rootFilter; this.rootFilter = rootFilter;
this.innerFilter = innerFilter; this.innerQuery = innerQuery;
} }
/** /**
@ -140,7 +144,10 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
* Get a {@link DocIdSet} that matches the inner documents. * Get a {@link DocIdSet} that matches the inner documents.
*/ */
public DocIdSetIterator innerDocs(LeafReaderContext ctx) throws IOException { public DocIdSetIterator innerDocs(LeafReaderContext ctx) throws IOException {
Scorer s = innerFilter.scorer(ctx); final IndexReaderContext topLevelCtx = ReaderUtil.getTopLevelContext(ctx);
IndexSearcher indexSearcher = new IndexSearcher(topLevelCtx);
Weight weight = indexSearcher.createNormalizedWeight(innerQuery, false);
Scorer s = weight.scorer(ctx);
return s == null ? null : s.iterator(); return s == null ? null : s.iterator();
} }
} }

View File

@ -31,7 +31,6 @@ import org.elasticsearch.index.query.QueryBuilder;
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.index.query.QueryShardException; import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException; import java.io.IOException;
@ -61,8 +60,8 @@ public class NestedInnerQueryParseSupport {
protected ObjectMapper nestedObjectMapper; protected ObjectMapper nestedObjectMapper;
private ObjectMapper parentObjectMapper; private ObjectMapper parentObjectMapper;
public NestedInnerQueryParseSupport(XContentParser parser, SearchContext searchContext) { public NestedInnerQueryParseSupport(XContentParser parser, QueryShardContext context) {
shardContext = searchContext.getQueryShardContext(); shardContext = context;
parseContext = shardContext.parseContext(); parseContext = shardContext.parseContext();
shardContext.reset(parser); shardContext.reset(parser);

View File

@ -43,9 +43,9 @@ import org.elasticsearch.index.fielddata.MultiGeoPointValues;
import org.elasticsearch.index.fielddata.NumericDoubleValues; import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues; import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.support.NestedInnerQueryParseSupport; import org.elasticsearch.index.query.support.NestedInnerQueryParseSupport;
import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.search.MultiValueMode;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -62,7 +62,7 @@ public class GeoDistanceSortParser implements SortParser {
} }
@Override @Override
public SortField parse(XContentParser parser, SearchContext context) throws Exception { public SortField parse(XContentParser parser, QueryShardContext context) throws Exception {
String fieldName = null; String fieldName = null;
List<GeoPoint> geoPoints = new ArrayList<>(); List<GeoPoint> geoPoints = new ArrayList<>();
DistanceUnit unit = DistanceUnit.DEFAULT; DistanceUnit unit = DistanceUnit.DEFAULT;
@ -71,7 +71,7 @@ public class GeoDistanceSortParser implements SortParser {
MultiValueMode sortMode = null; MultiValueMode sortMode = null;
NestedInnerQueryParseSupport nestedHelper = null; NestedInnerQueryParseSupport nestedHelper = null;
final boolean indexCreatedBeforeV2_0 = context.indexShard().indexSettings().getIndexVersionCreated().before(Version.V_2_0_0); final boolean indexCreatedBeforeV2_0 = context.indexVersionCreated().before(Version.V_2_0_0);
boolean coerce = GeoDistanceSortBuilder.DEFAULT_COERCE; boolean coerce = GeoDistanceSortBuilder.DEFAULT_COERCE;
boolean ignoreMalformed = GeoDistanceSortBuilder.DEFAULT_IGNORE_MALFORMED; boolean ignoreMalformed = GeoDistanceSortBuilder.DEFAULT_IGNORE_MALFORMED;
@ -155,12 +155,12 @@ public class GeoDistanceSortParser implements SortParser {
throw new IllegalArgumentException("sort_mode [sum] isn't supported for sorting by geo distance"); throw new IllegalArgumentException("sort_mode [sum] isn't supported for sorting by geo distance");
} }
MappedFieldType fieldType = context.smartNameFieldType(fieldName); MappedFieldType fieldType = context.fieldMapper(fieldName);
if (fieldType == null) { if (fieldType == null) {
throw new IllegalArgumentException("failed to find mapper for [" + fieldName + "] for geo distance based sort"); throw new IllegalArgumentException("failed to find mapper for [" + fieldName + "] for geo distance based sort");
} }
final MultiValueMode finalSortMode = sortMode; // final reference for use in the anonymous class final MultiValueMode finalSortMode = sortMode; // final reference for use in the anonymous class
final IndexGeoPointFieldData geoIndexFieldData = context.fieldData().getForField(fieldType); final IndexGeoPointFieldData geoIndexFieldData = context.getForField(fieldType);
final FixedSourceDistance[] distances = new FixedSourceDistance[geoPoints.size()]; final FixedSourceDistance[] distances = new FixedSourceDistance[geoPoints.size()];
for (int i = 0; i< geoPoints.size(); i++) { for (int i = 0; i< geoPoints.size(); i++) {
distances[i] = geoDistance.fixedSourceDistance(geoPoints.get(i).lat(), geoPoints.get(i).lon(), unit); distances[i] = geoDistance.fixedSourceDistance(geoPoints.get(i).lat(), geoPoints.get(i).lon(), unit);
@ -168,15 +168,16 @@ public class GeoDistanceSortParser implements SortParser {
final Nested nested; final Nested nested;
if (nestedHelper != null && nestedHelper.getPath() != null) { if (nestedHelper != null && nestedHelper.getPath() != null) {
BitSetProducer rootDocumentsFilter = context.bitsetFilterCache().getBitSetProducer(Queries.newNonNestedFilter()); BitSetProducer rootDocumentsFilter = context.bitsetFilter(Queries.newNonNestedFilter());
Query innerDocumentsFilter; Query innerDocumentsQuery;
if (nestedHelper.filterFound()) { if (nestedHelper.filterFound()) {
// TODO: use queries instead // TODO: use queries instead
innerDocumentsFilter = nestedHelper.getInnerFilter(); innerDocumentsQuery = nestedHelper.getInnerFilter();
} else { } else {
innerDocumentsFilter = nestedHelper.getNestedObjectMapper().nestedTypeFilter(); innerDocumentsQuery = nestedHelper.getNestedObjectMapper().nestedTypeFilter();
} }
nested = new Nested(rootDocumentsFilter, context.searcher().createNormalizedWeight(innerDocumentsFilter, false));
nested = new Nested(rootDocumentsFilter, innerDocumentsQuery);
} else { } else {
nested = null; nested = null;
} }

View File

@ -27,6 +27,7 @@ import org.apache.lucene.search.SortField;
import org.apache.lucene.search.join.BitSetProducer; import org.apache.lucene.search.join.BitSetProducer;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.BytesRefBuilder;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.fielddata.FieldData; import org.elasticsearch.index.fielddata.FieldData;
@ -37,6 +38,7 @@ import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues; import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource; import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource; import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.support.NestedInnerQueryParseSupport; import org.elasticsearch.index.query.support.NestedInnerQueryParseSupport;
import org.elasticsearch.script.LeafSearchScript; import org.elasticsearch.script.LeafSearchScript;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
@ -68,7 +70,7 @@ public class ScriptSortParser implements SortParser {
} }
@Override @Override
public SortField parse(XContentParser parser, SearchContext context) throws Exception { public SortField parse(XContentParser parser, QueryShardContext context) throws Exception {
ScriptParameterParser scriptParameterParser = new ScriptParameterParser(); ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
Script script = null; Script script = null;
String type = null; String type = null;
@ -122,19 +124,20 @@ public class ScriptSortParser implements SortParser {
script = new Script(scriptValue.script(), scriptValue.scriptType(), scriptParameterParser.lang(), params); script = new Script(scriptValue.script(), scriptValue.scriptType(), scriptParameterParser.lang(), params);
} }
} else if (params != null) { } else if (params != null) {
throw new SearchParseException(context, "script params must be specified inside script object", parser.getTokenLocation()); throw new ParsingException(parser.getTokenLocation(), "script params must be specified inside script object");
} }
if (script == null) { if (script == null) {
throw new SearchParseException(context, "_script sorting requires setting the script to sort by", parser.getTokenLocation()); throw new ParsingException(parser.getTokenLocation(), "_script sorting requires setting the script to sort by");
} }
if (type == null) { if (type == null) {
throw new SearchParseException(context, "_script sorting requires setting the type of the script", parser.getTokenLocation()); throw new ParsingException(parser.getTokenLocation(), "_script sorting requires setting the type of the script");
} }
final SearchScript searchScript = context.scriptService().search(context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap()); final SearchScript searchScript = context.getScriptService().search(
context.lookup(), script, ScriptContext.Standard.SEARCH, Collections.emptyMap());
if (STRING_SORT_TYPE.equals(type) && (sortMode == MultiValueMode.SUM || sortMode == MultiValueMode.AVG)) { if (STRING_SORT_TYPE.equals(type) && (sortMode == MultiValueMode.SUM || sortMode == MultiValueMode.AVG)) {
throw new SearchParseException(context, "type [string] doesn't support mode [" + sortMode + "]", parser.getTokenLocation()); throw new ParsingException(parser.getTokenLocation(), "type [string] doesn't support mode [" + sortMode + "]");
} }
if (sortMode == null) { if (sortMode == null) {
@ -144,7 +147,7 @@ public class ScriptSortParser implements SortParser {
// If nested_path is specified, then wrap the `fieldComparatorSource` in a `NestedFieldComparatorSource` // If nested_path is specified, then wrap the `fieldComparatorSource` in a `NestedFieldComparatorSource`
final Nested nested; final Nested nested;
if (nestedHelper != null && nestedHelper.getPath() != null) { if (nestedHelper != null && nestedHelper.getPath() != null) {
BitSetProducer rootDocumentsFilter = context.bitsetFilterCache().getBitSetProducer(Queries.newNonNestedFilter()); BitSetProducer rootDocumentsFilter = context.bitsetFilter(Queries.newNonNestedFilter());
Query innerDocumentsFilter; Query innerDocumentsFilter;
if (nestedHelper.filterFound()) { if (nestedHelper.filterFound()) {
// TODO: use queries instead // TODO: use queries instead
@ -152,7 +155,7 @@ public class ScriptSortParser implements SortParser {
} else { } else {
innerDocumentsFilter = nestedHelper.getNestedObjectMapper().nestedTypeFilter(); innerDocumentsFilter = nestedHelper.getNestedObjectMapper().nestedTypeFilter();
} }
nested = new Nested(rootDocumentsFilter, context.searcher().createNormalizedWeight(innerDocumentsFilter, false)); nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
} else { } else {
nested = null; nested = null;
} }
@ -205,7 +208,7 @@ public class ScriptSortParser implements SortParser {
}; };
break; break;
default: default:
throw new SearchParseException(context, "custom script sort type [" + type + "] not supported", parser.getTokenLocation()); throw new ParsingException(parser.getTokenLocation(), "custom script sort type [" + type + "] not supported");
} }
return new SortField("_script", fieldComparatorSource, reverse); return new SortField("_script", fieldComparatorSource, reverse);

View File

@ -140,7 +140,7 @@ public class SortParseElement implements SearchParseElement {
addSortField(context, sortFields, fieldName, reverse, unmappedType, missing, sortMode, nestedFilterParseHelper); addSortField(context, sortFields, fieldName, reverse, unmappedType, missing, sortMode, nestedFilterParseHelper);
} else { } else {
if (PARSERS.containsKey(fieldName)) { if (PARSERS.containsKey(fieldName)) {
sortFields.add(PARSERS.get(fieldName).parse(parser, context)); sortFields.add(PARSERS.get(fieldName).parse(parser, context.getQueryShardContext()));
} else { } else {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) { if (token == XContentParser.Token.FIELD_NAME) {
@ -168,7 +168,7 @@ public class SortParseElement implements SearchParseElement {
sortMode = MultiValueMode.fromString(parser.text()); sortMode = MultiValueMode.fromString(parser.text());
} else if ("nested_path".equals(innerJsonName) || "nestedPath".equals(innerJsonName)) { } else if ("nested_path".equals(innerJsonName) || "nestedPath".equals(innerJsonName)) {
if (nestedFilterParseHelper == null) { if (nestedFilterParseHelper == null) {
nestedFilterParseHelper = new NestedInnerQueryParseSupport(parser, context); nestedFilterParseHelper = new NestedInnerQueryParseSupport(parser, context.getQueryShardContext());
} }
nestedFilterParseHelper.setPath(parser.text()); nestedFilterParseHelper.setPath(parser.text());
} else { } else {
@ -177,7 +177,7 @@ public class SortParseElement implements SearchParseElement {
} else if (token == XContentParser.Token.START_OBJECT) { } else if (token == XContentParser.Token.START_OBJECT) {
if ("nested_filter".equals(innerJsonName) || "nestedFilter".equals(innerJsonName)) { if ("nested_filter".equals(innerJsonName) || "nestedFilter".equals(innerJsonName)) {
if (nestedFilterParseHelper == null) { if (nestedFilterParseHelper == null) {
nestedFilterParseHelper = new NestedInnerQueryParseSupport(parser, context); nestedFilterParseHelper = new NestedInnerQueryParseSupport(parser, context.getQueryShardContext());
} }
nestedFilterParseHelper.filter(); nestedFilterParseHelper.filter();
} else { } else {
@ -239,14 +239,13 @@ public class SortParseElement implements SearchParseElement {
final Nested nested; final Nested nested;
if (nestedHelper != null && nestedHelper.getPath() != null) { if (nestedHelper != null && nestedHelper.getPath() != null) {
BitSetProducer rootDocumentsFilter = context.bitsetFilterCache().getBitSetProducer(Queries.newNonNestedFilter()); BitSetProducer rootDocumentsFilter = context.bitsetFilterCache().getBitSetProducer(Queries.newNonNestedFilter());
Query innerDocumentsFilter; Query innerDocumentsQuery;
if (nestedHelper.filterFound()) { if (nestedHelper.filterFound()) {
// TODO: use queries instead innerDocumentsQuery = nestedHelper.getInnerFilter();
innerDocumentsFilter = nestedHelper.getInnerFilter();
} else { } else {
innerDocumentsFilter = nestedHelper.getNestedObjectMapper().nestedTypeFilter(); innerDocumentsQuery = nestedHelper.getNestedObjectMapper().nestedTypeFilter();
} }
nested = new Nested(rootDocumentsFilter, context.searcher().createNormalizedWeight(innerDocumentsFilter, false)); nested = new Nested(rootDocumentsFilter, innerDocumentsQuery);
} else { } else {
nested = null; nested = null;
} }

View File

@ -21,7 +21,7 @@ package org.elasticsearch.search.sort;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.index.query.QueryShardContext;
/** /**
* *
@ -30,5 +30,5 @@ public interface SortParser {
String[] names(); String[] names();
SortField parse(XContentParser parser, SearchContext context) throws Exception; SortField parse(XContentParser parser, QueryShardContext context) throws Exception;
} }

View File

@ -168,7 +168,7 @@ public abstract class AbstractFieldDataTestCase extends ESSingleNodeTestCase {
protected Nested createNested(IndexSearcher searcher, Query parentFilter, Query childFilter) throws IOException { protected Nested createNested(IndexSearcher searcher, Query parentFilter, Query childFilter) throws IOException {
BitsetFilterCache s = indexService.cache().bitsetFilterCache(); BitsetFilterCache s = indexService.cache().bitsetFilterCache();
return new Nested(s.getBitSetProducer(parentFilter), searcher.createNormalizedWeight(childFilter, false)); return new Nested(s.getBitSetProducer(parentFilter), childFilter);
} }
public void testEmpty() throws Exception { public void testEmpty() throws Exception {

View File

@ -50,7 +50,7 @@ public class SortParserTests extends ESSingleNodeTestCase {
XContentParser parser = XContentHelper.createParser(sortBuilder.bytes()); XContentParser parser = XContentHelper.createParser(sortBuilder.bytes());
parser.nextToken(); parser.nextToken();
GeoDistanceSortParser geoParser = new GeoDistanceSortParser(); GeoDistanceSortParser geoParser = new GeoDistanceSortParser();
geoParser.parse(parser, context); geoParser.parse(parser, context.getQueryShardContext());
sortBuilder = jsonBuilder(); sortBuilder = jsonBuilder();
sortBuilder.startObject(); sortBuilder.startObject();
@ -139,6 +139,6 @@ public class SortParserTests extends ESSingleNodeTestCase {
XContentParser parser = XContentHelper.createParser(sortBuilder.bytes()); XContentParser parser = XContentHelper.createParser(sortBuilder.bytes());
parser.nextToken(); parser.nextToken();
GeoDistanceSortParser geoParser = new GeoDistanceSortParser(); GeoDistanceSortParser geoParser = new GeoDistanceSortParser();
geoParser.parse(parser, context); geoParser.parse(parser, context.getQueryShardContext());
} }
} }