Respect cluster alias in `_index` aggs and queries (#25885)

Today when we aggregate on the `_index` field the cross cluster search
alias is not taken into account. Neither is it respected when we search
on the field. This change adds support for cluster alias when the cluster
alias is present on the `_index` field.

Closes #25606
This commit is contained in:
Simon Willnauer 2017-07-26 09:16:52 +02:00 committed by GitHub
parent 2f8def11b5
commit 634ce90dc0
48 changed files with 285 additions and 124 deletions

View File

@ -415,7 +415,7 @@ public class MetaDataCreateIndexService extends AbstractComponent {
// the context is only used for validation so it's fine to pass fake values for the shard id and the current
// timestamp
final QueryShardContext queryShardContext = indexService.newQueryShardContext(0, null, () -> 0L);
final QueryShardContext queryShardContext = indexService.newQueryShardContext(0, null, () -> 0L, null);
for (Alias alias : request.aliases()) {
if (Strings.hasLength(alias.filter())) {

View File

@ -150,7 +150,7 @@ public class MetaDataIndexAliasesService extends AbstractComponent {
}
// the context is only used for validation so it's fine to pass fake values for the shard id and the current
// timestamp
aliasValidator.validateAliasFilter(alias, filter, indexService.newQueryShardContext(0, null, () -> 0L),
aliasValidator.validateAliasFilter(alias, filter, indexService.newQueryShardContext(0, null, () -> 0L, null),
xContentRegistry);
}
};

View File

@ -150,7 +150,7 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
this.mapperService = new MapperService(indexSettings, registry.build(indexSettings), xContentRegistry, similarityService,
mapperRegistry,
// we parse all percolator queries as they would be parsed on shard 0
() -> newQueryShardContext(0, null, System::currentTimeMillis));
() -> newQueryShardContext(0, null, System::currentTimeMillis, null));
this.indexFieldData = new IndexFieldDataService(indexSettings, indicesFieldDataCache, circuitBreakerService, mapperService);
if (indexSettings.getIndexSortConfig().hasIndexSort()) {
// we delay the actual creation of the sort order for this index because the mapping has not been merged yet.
@ -467,12 +467,9 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
* Passing a {@code null} {@link IndexReader} will return a valid context, however it won't be able to make
* {@link IndexReader}-specific optimizations, such as rewriting containing range queries.
*/
public QueryShardContext newQueryShardContext(int shardId, IndexReader indexReader, LongSupplier nowInMillis) {
return new QueryShardContext(
shardId, indexSettings, indexCache.bitsetFilterCache(), indexFieldData, mapperService(),
similarityService(), scriptService, xContentRegistry,
client, indexReader,
nowInMillis);
public QueryShardContext newQueryShardContext(int shardId, IndexReader indexReader, LongSupplier nowInMillis, String clusterAlias) {
return new QueryShardContext(shardId, indexSettings, indexCache.bitsetFilterCache(), indexFieldData::getForField, mapperService(),
similarityService(), scriptService, xContentRegistry, client, indexReader, nowInMillis, clusterAlias);
}
/**

View File

@ -73,6 +73,7 @@ public class ConstantIndexFieldData extends AbstractIndexOrdinalsFieldData {
this.value = value;
}
@Override
public long ramBytesUsed() {
return 0;
@ -125,7 +126,7 @@ public class ConstantIndexFieldData extends AbstractIndexOrdinalsFieldData {
}
private final AtomicOrdinalsFieldData atomicFieldData;
private final ConstantAtomicFieldData atomicFieldData;
private ConstantIndexFieldData(IndexSettings indexSettings, String name, String value) {
super(indexSettings, name, null, null,
@ -167,4 +168,8 @@ public class ConstantIndexFieldData extends AbstractIndexOrdinalsFieldData {
return loadGlobal(indexReader);
}
public String getValue() {
return atomicFieldData.value;
}
}

View File

@ -123,7 +123,7 @@ public class IndexFieldMapper extends MetadataFieldMapper {
*/
@Override
public Query termQuery(Object value, @Nullable QueryShardContext context) {
if (isSameIndex(value, context.index().getName())) {
if (isSameIndex(value, context.getFullyQualifiedIndexName())) {
return Queries.newMatchAllQuery();
} else {
return Queries.newMatchNoDocsQuery("Index didn't match. Index queried: " + context.index().getName() + " vs. " + value);
@ -136,14 +136,15 @@ public class IndexFieldMapper extends MetadataFieldMapper {
return super.termsQuery(values, context);
}
for (Object value : values) {
if (isSameIndex(value, context.index().getName())) {
if (isSameIndex(value, context.getFullyQualifiedIndexName())) {
// No need to OR these clauses - we can only logically be
// running in the context of just one of these index names.
return Queries.newMatchAllQuery();
}
}
// None of the listed index names are this one
return Queries.newMatchNoDocsQuery("Index didn't match. Index queried: " + context.index().getName() + " vs. " + values);
return Queries.newMatchNoDocsQuery("Index didn't match. Index queried: " + context.getFullyQualifiedIndexName()
+ " vs. " + values);
}
private boolean isSameIndex(Object value, String indexName) {

View File

@ -39,20 +39,21 @@ import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.IndexAnalyzers;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.fielddata.plain.ConstantIndexFieldData;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.IndexFieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.MetadataFieldMapper;
import org.elasticsearch.index.mapper.ObjectMapper;
import org.elasticsearch.index.mapper.TextFieldMapper;
import org.elasticsearch.index.query.support.NestedScope;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.TemplateScript;
import org.elasticsearch.search.lookup.SearchLookup;
import org.elasticsearch.transport.RemoteClusterAware;
import java.io.IOException;
import java.util.Arrays;
@ -60,6 +61,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.LongSupplier;
import static java.util.Collections.unmodifiableMap;
@ -74,12 +76,14 @@ public class QueryShardContext extends QueryRewriteContext {
private final MapperService mapperService;
private final SimilarityService similarityService;
private final BitsetFilterCache bitsetFilterCache;
private final IndexFieldDataService indexFieldDataService;
private final Function<MappedFieldType, IndexFieldData<?>> indexFieldDataService;
private final int shardId;
private final IndexReader reader;
private final String clusterAlias;
private String[] types = Strings.EMPTY_ARRAY;
private boolean cachable = true;
private final SetOnce<Boolean> frozen = new SetOnce<>();
private final String fullyQualifiedIndexName;
public void setTypes(String... types) {
this.types = types;
@ -96,27 +100,28 @@ public class QueryShardContext extends QueryRewriteContext {
private boolean isFilter;
public QueryShardContext(int shardId, IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache,
IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService,
ScriptService scriptService, NamedXContentRegistry xContentRegistry,
Client client, IndexReader reader, LongSupplier nowInMillis) {
Function<MappedFieldType, IndexFieldData<?>> indexFieldDataLookup, MapperService mapperService,
SimilarityService similarityService, ScriptService scriptService, NamedXContentRegistry xContentRegistry,
Client client, IndexReader reader, LongSupplier nowInMillis, String clusterAlias) {
super(xContentRegistry, client, nowInMillis);
this.shardId = shardId;
this.similarityService = similarityService;
this.mapperService = mapperService;
this.bitsetFilterCache = bitsetFilterCache;
this.indexFieldDataService = indexFieldDataService;
this.indexFieldDataService = indexFieldDataLookup;
this.allowUnmappedFields = indexSettings.isDefaultAllowUnmappedFields();
this.nestedScope = new NestedScope();
this.scriptService = scriptService;
this.indexSettings = indexSettings;
this.reader = reader;
this.clusterAlias = clusterAlias;
this.fullyQualifiedIndexName = RemoteClusterAware.buildRemoteIndexName(clusterAlias, indexSettings.getIndex().getName());
}
public QueryShardContext(QueryShardContext source) {
this(source.shardId, source.indexSettings, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService,
source.similarityService, source.scriptService, source.getXContentRegistry(), source.client,
source.reader, source.nowInMillis);
source.reader, source.nowInMillis, source.clusterAlias);
this.types = source.getTypes();
}
@ -156,8 +161,14 @@ public class QueryShardContext extends QueryRewriteContext {
return bitsetFilterCache.getBitSetProducer(filter);
}
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType mapper) {
return indexFieldDataService.getForField(mapper);
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
if (clusterAlias != null && IndexFieldMapper.NAME.equals(fieldType.name())) {
// this is a "hack" to make the _index field data aware of cross cluster search cluster aliases.
ConstantIndexFieldData ifd = (ConstantIndexFieldData) indexFieldDataService.apply(fieldType);
return (IFD) new ConstantIndexFieldData.Builder(m -> fullyQualifiedIndexName)
.build(indexSettings, fieldType, null, null, mapperService);
}
return (IFD) indexFieldDataService.apply(fieldType);
}
public void addNamedQuery(String name, Query query) {
@ -420,4 +431,10 @@ public class QueryShardContext extends QueryRewriteContext {
return reader;
}
/**
* Returns the fully qualified index name including a remote cluster alias if applicable
*/
public String getFullyQualifiedIndexName() {
return fullyQualifiedIndexName;
}
}

View File

@ -39,6 +39,7 @@ import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
@ -95,7 +96,6 @@ final class DefaultSearchContext extends SearchContext {
private final BigArrays bigArrays;
private final IndexShard indexShard;
private final IndexService indexService;
private final ResponseCollectorService responseCollectorService;
private final ContextIndexSearcher searcher;
private final DfsSearchResult dfsResult;
private final QuerySearchResult queryResult;
@ -150,7 +150,6 @@ final class DefaultSearchContext extends SearchContext {
private final long originNanoTime = System.nanoTime();
private volatile long lastAccessTime = -1;
private Profilers profilers;
private ExecutorService searchExecutor;
private final Map<String, SearchExtBuilder> searchExtBuilders = new HashMap<>();
private final Map<Class<?>, Collector> queryCollectors = new HashMap<>();
@ -159,7 +158,7 @@ final class DefaultSearchContext extends SearchContext {
DefaultSearchContext(long id, ShardSearchRequest request, SearchShardTarget shardTarget, Engine.Searcher engineSearcher,
IndexService indexService, IndexShard indexShard, BigArrays bigArrays, Counter timeEstimateCounter,
TimeValue timeout, FetchPhase fetchPhase, ResponseCollectorService responseCollectorService) {
TimeValue timeout, FetchPhase fetchPhase, String clusterAlias) {
this.id = id;
this.request = request;
this.fetchPhase = fetchPhase;
@ -173,11 +172,11 @@ final class DefaultSearchContext extends SearchContext {
this.fetchResult = new FetchSearchResult(id, shardTarget);
this.indexShard = indexShard;
this.indexService = indexService;
this.responseCollectorService = responseCollectorService;
this.searcher = new ContextIndexSearcher(engineSearcher, indexService.cache().query(), indexShard.getQueryCachingPolicy());
this.timeEstimateCounter = timeEstimateCounter;
this.timeout = timeout;
queryShardContext = indexService.newQueryShardContext(request.shardId().id(), searcher.getIndexReader(), request::nowInMillis);
queryShardContext = indexService.newQueryShardContext(request.shardId().id(), searcher.getIndexReader(), request::nowInMillis,
clusterAlias);
queryShardContext.setTypes(request.types());
queryBoost = request.indexBoost();
}
@ -496,9 +495,10 @@ final class DefaultSearchContext extends SearchContext {
return indexService.cache().bitsetFilterCache();
}
@Override
public IndexFieldDataService fieldData() {
return indexService.fieldData();
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
return queryShardContext.getForField(fieldType);
}
@Override

View File

@ -573,7 +573,7 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv
final DefaultSearchContext searchContext = new DefaultSearchContext(idGenerator.incrementAndGet(), request, shardTarget,
engineSearcher, indexService, indexShard, bigArrays, threadPool.estimatedTimeInMillisCounter(), timeout, fetchPhase,
responseCollectorService);
request.getClusterAlias());
boolean success = false;
try {
// we clone the query shard context here just for rewriting otherwise we

View File

@ -72,7 +72,7 @@ public final class DocValueFieldsFetchSubPhase implements FetchSubPhase {
if (subReaderContext == null || hit.docId() >= subReaderContext.docBase + subReaderContext.reader().maxDoc()) {
int readerIndex = ReaderUtil.subIndex(hit.docId(), context.searcher().getIndexReader().leaves());
subReaderContext = context.searcher().getIndexReader().leaves().get(readerIndex);
data = context.fieldData().getForField(fieldType).load(subReaderContext);
data = context.getForField(fieldType).load(subReaderContext);
values = data.getScriptValues();
}
int subDocId = hit.docId() - subReaderContext.docBase;

View File

@ -28,6 +28,7 @@ import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
@ -262,8 +263,8 @@ public abstract class FilteredSearchContext extends SearchContext {
}
@Override
public IndexFieldDataService fieldData() {
return in.fieldData();
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
return in.getForField(fieldType);
}
@Override

View File

@ -34,6 +34,7 @@ import org.elasticsearch.common.util.concurrent.AbstractRefCounted;
import org.elasticsearch.common.util.concurrent.RefCounted;
import org.elasticsearch.common.util.iterable.Iterables;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
@ -210,7 +211,7 @@ public abstract class SearchContext extends AbstractRefCounted implements Releas
public abstract BitsetFilterCache bitsetFilterCache();
public abstract IndexFieldDataService fieldData();
public abstract <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType);
public abstract TimeValue timeout();

View File

@ -20,20 +20,24 @@ package org.elasticsearch.search.lookup;
import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import java.util.function.Function;
public class DocLookup {
private final MapperService mapperService;
private final IndexFieldDataService fieldDataService;
private final Function<MappedFieldType, IndexFieldData<?>> fieldDataLookup;
@Nullable
private final String[] types;
DocLookup(MapperService mapperService, IndexFieldDataService fieldDataService, @Nullable String[] types) {
DocLookup(MapperService mapperService, Function<MappedFieldType, IndexFieldData<?>> fieldDataLookup, @Nullable String[] types) {
this.mapperService = mapperService;
this.fieldDataService = fieldDataService;
this.fieldDataLookup = fieldDataLookup;
this.types = types;
}
@ -41,12 +45,12 @@ public class DocLookup {
return this.mapperService;
}
public IndexFieldDataService fieldDataService() {
return this.fieldDataService;
public IndexFieldData<?> getForField(MappedFieldType fieldType) {
return fieldDataLookup.apply(fieldType);
}
public LeafDocLookup getLeafDocLookup(LeafReaderContext context) {
return new LeafDocLookup(mapperService, fieldDataService, types, context);
return new LeafDocLookup(mapperService, fieldDataLookup, types, context);
}
public String[] getTypes() {

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.lookup;
import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.index.mapper.MappedFieldType;
@ -34,13 +35,14 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
public class LeafDocLookup implements Map<String, ScriptDocValues<?>> {
private final Map<String, ScriptDocValues<?>> localCacheFieldData = new HashMap<>(4);
private final MapperService mapperService;
private final IndexFieldDataService fieldDataService;
private final Function<MappedFieldType, IndexFieldData<?>> fieldDataLookup;
@Nullable
private final String[] types;
@ -49,9 +51,10 @@ public class LeafDocLookup implements Map<String, ScriptDocValues<?>> {
private int docId = -1;
LeafDocLookup(MapperService mapperService, IndexFieldDataService fieldDataService, @Nullable String[] types, LeafReaderContext reader) {
LeafDocLookup(MapperService mapperService, Function<MappedFieldType, IndexFieldData<?>> fieldDataLookup, @Nullable String[] types,
LeafReaderContext reader) {
this.mapperService = mapperService;
this.fieldDataService = fieldDataService;
this.fieldDataLookup = fieldDataLookup;
this.types = types;
this.reader = reader;
}
@ -60,8 +63,8 @@ public class LeafDocLookup implements Map<String, ScriptDocValues<?>> {
return this.mapperService;
}
public IndexFieldDataService fieldDataService() {
return this.fieldDataService;
public IndexFieldData<?> getForField(MappedFieldType fieldType) {
return fieldDataLookup.apply(fieldType);
}
public void setDocument(int docId) {
@ -83,7 +86,7 @@ public class LeafDocLookup implements Map<String, ScriptDocValues<?>> {
scriptValues = AccessController.doPrivileged(new PrivilegedAction<ScriptDocValues<?>>() {
@Override
public ScriptDocValues<?> run() {
return fieldDataService.getForField(fieldType).load(reader).getScriptValues();
return fieldDataLookup.apply(fieldType).load(reader).getScriptValues();
}
});
localCacheFieldData.put(fieldName, scriptValues);

View File

@ -21,9 +21,13 @@ package org.elasticsearch.search.lookup;
import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import java.util.function.Function;
public class SearchLookup {
final DocLookup docMap;
@ -32,8 +36,9 @@ public class SearchLookup {
final FieldsLookup fieldsLookup;
public SearchLookup(MapperService mapperService, IndexFieldDataService fieldDataService, @Nullable String[] types) {
docMap = new DocLookup(mapperService, fieldDataService, types);
public SearchLookup(MapperService mapperService, Function<MappedFieldType, IndexFieldData<?>> fieldDataLookup,
@Nullable String[] types) {
docMap = new DocLookup(mapperService, fieldDataLookup, types);
sourceLookup = new SourceLookup();
fieldsLookup = new FieldsLookup(mapperService, types);
}

View File

@ -105,7 +105,7 @@ public class QueryPhase implements SearchPhase {
// here to make sure it happens during the QUERY phase
aggregationPhase.preProcess(searchContext);
Sort indexSort = searchContext.mapperService().getIndexSettings().getIndexSortConfig()
.buildIndexSort(searchContext.mapperService()::fullName, searchContext.fieldData()::getForField);
.buildIndexSort(searchContext.mapperService()::fullName, searchContext::getForField);
final ContextIndexSearcher searcher = searchContext.searcher();
boolean rescore = execute(searchContext, searchContext.searcher(), searcher::setCheckCancelled, indexSort);

View File

@ -169,7 +169,7 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
QueryShardContext context = new QueryShardContext(0,
new IndexSettings(IndexMetaData.builder("foo").settings(indexSettings).build(),
indexSettings),
null, null, null, null, null, xContentRegistry(), null, null, () -> nowInMillis);
null, null, null, null, null, xContentRegistry(), null, null, () -> nowInMillis, null);
MappedFieldType ft = createDefaultFieldType();
ft.setName("field");
String date = "2015-10-12T14:10:55";
@ -191,7 +191,7 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1).build();
QueryShardContext context = new QueryShardContext(0,
new IndexSettings(IndexMetaData.builder("foo").settings(indexSettings).build(), indexSettings),
null, null, null, null, null, xContentRegistry(), null, null, () -> nowInMillis);
null, null, null, null, null, xContentRegistry(), null, null, () -> nowInMillis, null);
MappedFieldType ft = createDefaultFieldType();
ft.setName("field");
String date1 = "2015-10-12T14:10:55";

View File

@ -46,7 +46,7 @@ public class DoubleIndexingDocTests extends ESSingleNodeTestCase {
IndexService index = createIndex("test");
client().admin().indices().preparePutMapping("test").setType("type").setSource(mapping, XContentType.JSON).get();
DocumentMapper mapper = index.mapperService().documentMapper("type");
QueryShardContext context = index.newQueryShardContext(0, null, () -> 0L);
QueryShardContext context = index.newQueryShardContext(0, null, () -> 0L, null);
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject()

View File

@ -63,7 +63,7 @@ public class ExternalFieldMapperTests extends ESSingleNodeTestCase {
Collections.singletonMap(ExternalMetadataMapper.CONTENT_TYPE, new ExternalMetadataMapper.TypeParser()));
Supplier<QueryShardContext> queryShardContext = () -> {
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); });
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); }, null);
};
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.getIndexAnalyzers(), indexService.xContentRegistry(), indexService.similarityService(), mapperRegistry,
@ -114,7 +114,7 @@ public class ExternalFieldMapperTests extends ESSingleNodeTestCase {
MapperRegistry mapperRegistry = new MapperRegistry(mapperParsers, Collections.emptyMap());
Supplier<QueryShardContext> queryShardContext = () -> {
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); });
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); }, null);
};
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.getIndexAnalyzers(), indexService.xContentRegistry(), indexService.similarityService(), mapperRegistry,
@ -180,7 +180,7 @@ public class ExternalFieldMapperTests extends ESSingleNodeTestCase {
MapperRegistry mapperRegistry = new MapperRegistry(mapperParsers, Collections.emptyMap());
Supplier<QueryShardContext> queryShardContext = () -> {
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); });
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); }, null);
};
DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(),
indexService.getIndexAnalyzers(), indexService.xContentRegistry(), indexService.similarityService(), mapperRegistry,

View File

@ -239,7 +239,7 @@ public class FieldNamesFieldMapperTests extends ESSingleNodeTestCase {
);
final MapperRegistry mapperRegistry = indicesModule.getMapperRegistry();
Supplier<QueryShardContext> queryShardContext = () -> {
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); });
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); }, null);
};
MapperService mapperService = new MapperService(indexService.getIndexSettings(), indexService.getIndexAnalyzers(),
indexService.xContentRegistry(), indexService.similarityService(), mapperRegistry, queryShardContext);

View File

@ -83,7 +83,7 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings);
QueryShardContext context = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(),
null, null, () -> nowInMillis);
null, null, () -> nowInMillis, null);
RangeFieldMapper.RangeFieldType ft = new RangeFieldMapper.RangeFieldType(type, Version.CURRENT);
ft.setName(FIELDNAME);
ft.setIndexOptions(IndexOptions.DOCS);

View File

@ -26,7 +26,6 @@ import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.MultiPhraseQuery;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexService;
@ -38,7 +37,6 @@ import org.junit.Before;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
/**
* Makes sure that graph analysis is disabled with shingle filters of different size
@ -71,7 +69,7 @@ public class DisableGraphQueryTests extends ESSingleNodeTestCase {
indexService = createIndex("test", settings, "t",
"text_shingle", "type=text,analyzer=text_shingle",
"text_shingle_unigram", "type=text,analyzer=text_shingle_unigram");
shardContext = indexService.newQueryShardContext(0, null, () -> 0L);
shardContext = indexService.newQueryShardContext(0, null, () -> 0L, null);
// parsed queries for "text_shingle_unigram:(foo bar baz)" with query parsers
// that ignores position length attribute

View File

@ -18,14 +18,27 @@
*/
package org.elasticsearch.index.query;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.plain.AbstractAtomicOrdinalsFieldData;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.IndexFieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.TextFieldMapper;
import org.elasticsearch.test.ESTestCase;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
@ -38,18 +51,23 @@ import static org.mockito.Mockito.when;
public class QueryShardContextTests extends ESTestCase {
public void testFailIfFieldMappingNotFound() {
IndexMetaData.Builder indexMetadata = new IndexMetaData.Builder("index");
indexMetadata.settings(Settings.builder().put("index.version.created", Version.CURRENT)
IndexMetaData.Builder indexMetadataBuilder = new IndexMetaData.Builder("index");
indexMetadataBuilder.settings(Settings.builder().put("index.version.created", Version.CURRENT)
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 1)
);
IndexSettings indexSettings = new IndexSettings(indexMetadata.build(), Settings.EMPTY);
IndexMetaData indexMetaData = indexMetadataBuilder.build();
IndexSettings indexSettings = new IndexSettings(indexMetaData, Settings.EMPTY);
MapperService mapperService = mock(MapperService.class);
when(mapperService.getIndexSettings()).thenReturn(indexSettings);
when(mapperService.index()).thenReturn(indexMetaData.getIndex());
final long nowInMillis = randomNonNegativeLong();
QueryShardContext context = new QueryShardContext(
0, indexSettings, null, null, mapperService, null, null, xContentRegistry(), null, null,
() -> nowInMillis);
0, indexSettings, null, mappedFieldType ->
mappedFieldType.fielddataBuilder().build(indexSettings, mappedFieldType, null, null, null)
, mapperService, null, null, xContentRegistry(), null, null,
() -> nowInMillis, null);
context.setAllowUnmappedFields(false);
MappedFieldType fieldType = new TextFieldMapper.TextFieldType();
@ -74,4 +92,47 @@ public class QueryShardContextTests extends ESTestCase {
assertThat(result.name(), equalTo("name"));
}
public void testClusterAlias() throws IOException {
IndexMetaData.Builder indexMetadataBuilder = new IndexMetaData.Builder("index");
indexMetadataBuilder.settings(Settings.builder().put("index.version.created", Version.CURRENT)
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 1)
);
IndexMetaData indexMetaData = indexMetadataBuilder.build();
IndexSettings indexSettings = new IndexSettings(indexMetaData, Settings.EMPTY);
MapperService mapperService = mock(MapperService.class);
when(mapperService.getIndexSettings()).thenReturn(indexSettings);
when(mapperService.index()).thenReturn(indexMetaData.getIndex());
final long nowInMillis = randomNonNegativeLong();
Mapper.BuilderContext ctx = new Mapper.BuilderContext(indexSettings.getSettings(), new ContentPath());
IndexFieldMapper mapper = new IndexFieldMapper.Builder(null).build(ctx);
final String clusterAlias = randomBoolean() ? null : "remote_cluster";
QueryShardContext context = new QueryShardContext(
0, indexSettings, null, mappedFieldType ->
mappedFieldType.fielddataBuilder().build(indexSettings, mappedFieldType, null, null, mapperService)
, mapperService, null, null, xContentRegistry(), null, null,
() -> nowInMillis, clusterAlias);
IndexFieldData<?> forField = context.getForField(mapper.fieldType());
String expected = clusterAlias == null ? indexMetaData.getIndex().getName()
: clusterAlias + ":" + indexMetaData.getIndex().getName();
assertEquals(expected, ((AbstractAtomicOrdinalsFieldData)forField.load(null)).getOrdinalsValues().lookupOrd(0).utf8ToString());
Query query = mapper.fieldType().termQuery("index", context);
if (clusterAlias == null) {
assertEquals(Queries.newMatchAllQuery(), query);
} else {
assertThat(query, Matchers.instanceOf(MatchNoDocsQuery.class));
}
query = mapper.fieldType().termQuery("remote_cluster:index", context);
if (clusterAlias != null) {
assertEquals(Queries.newMatchAllQuery(), query);
} else {
assertThat(query, Matchers.instanceOf(MatchNoDocsQuery.class));
}
query = mapper.fieldType().termQuery("something:else", context);
assertThat(query, Matchers.instanceOf(MatchNoDocsQuery.class));
}
}

View File

@ -37,7 +37,7 @@ public class RangeQueryRewriteTests extends ESSingleNodeTestCase {
IndexService indexService = createIndex("test");
IndexReader reader = new MultiReader();
QueryRewriteContext context = new QueryShardContext(0, indexService.getIndexSettings(), null, null, indexService.mapperService(),
null, null, xContentRegistry(), null, reader, null);
null, null, xContentRegistry(), null, reader, null, null);
RangeQueryBuilder range = new RangeQueryBuilder("foo");
assertEquals(Relation.DISJOINT, range.getRelation(context));
}
@ -54,7 +54,7 @@ public class RangeQueryRewriteTests extends ESSingleNodeTestCase {
indexService.mapperService().merge("type",
new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false);
QueryRewriteContext context = new QueryShardContext(0, indexService.getIndexSettings(), null, null, indexService.mapperService(),
null, null, xContentRegistry(), null, null, null);
null, null, xContentRegistry(), null, null, null, null);
RangeQueryBuilder range = new RangeQueryBuilder("foo");
// can't make assumptions on a missing reader, so it must return INTERSECT
assertEquals(Relation.INTERSECTS, range.getRelation(context));
@ -73,7 +73,7 @@ public class RangeQueryRewriteTests extends ESSingleNodeTestCase {
new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false);
IndexReader reader = new MultiReader();
QueryRewriteContext context = new QueryShardContext(0, indexService.getIndexSettings(), null, null, indexService.mapperService(),
null, null, xContentRegistry(), null, reader, null);
null, null, xContentRegistry(), null, reader, null, null);
RangeQueryBuilder range = new RangeQueryBuilder("foo");
// no values -> DISJOINT
assertEquals(Relation.DISJOINT, range.getRelation(context));

View File

@ -177,7 +177,7 @@ public class SimpleQueryParserTests extends ESTestCase {
IndexMetaData indexState = IndexMetaData.builder("index").settings(indexSettings).build();
IndexSettings settings = new IndexSettings(indexState, Settings.EMPTY);
QueryShardContext mockShardContext = new QueryShardContext(0, settings, null, null, null, null, null, xContentRegistry(),
null, null, System::currentTimeMillis) {
null, null, System::currentTimeMillis, null) {
@Override
public MappedFieldType fieldMapper(String name) {
return new MockFieldMapper.FakeFieldType();
@ -191,7 +191,7 @@ public class SimpleQueryParserTests extends ESTestCase {
// Now check what happens if foo.quote does not exist
mockShardContext = new QueryShardContext(0, settings, null, null, null, null, null, xContentRegistry(),
null, null, System::currentTimeMillis) {
null, null, System::currentTimeMillis, null) {
@Override
public MappedFieldType fieldMapper(String name) {
if (name.equals("foo.quote")) {

View File

@ -75,7 +75,7 @@ public class CustomQueryParserIT extends ESIntegTestCase {
private static QueryShardContext queryShardContext() {
IndicesService indicesService = internalCluster().getDataNodeInstance(IndicesService.class);
return indicesService.indexServiceSafe(resolveIndex("index")).newQueryShardContext(
randomInt(20), null, () -> { throw new UnsupportedOperationException(); });
randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null);
}
//see #11120

View File

@ -21,9 +21,6 @@ package org.elasticsearch.index.search;
import org.apache.lucene.index.Term;
import org.apache.lucene.queries.BlendedTermQuery;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
@ -89,7 +86,7 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
public void testCrossFieldMultiMatchQuery() throws IOException {
QueryShardContext queryShardContext = indexService.newQueryShardContext(
randomInt(20), null, () -> { throw new UnsupportedOperationException(); });
randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null);
queryShardContext.setAllowUnmappedFields(true);
Query parsedQuery = multiMatchQuery("banon").field("name.first", 2).field("name.last", 3).field("foobar").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).toQuery(queryShardContext);
try (Engine.Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
@ -114,7 +111,7 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
float[] boosts = new float[] {2, 3};
Query expected = BlendedTermQuery.dismaxBlendedQuery(terms, boosts, 1.0f);
Query actual = MultiMatchQuery.blendTerm(
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }),
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null),
new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
@ -130,7 +127,7 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
float[] boosts = new float[] {200, 30};
Query expected = BlendedTermQuery.dismaxBlendedQuery(terms, boosts, 1.0f);
Query actual = MultiMatchQuery.blendTerm(
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }),
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null),
new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
@ -149,7 +146,7 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
float[] boosts = new float[] {2};
Query expected = BlendedTermQuery.dismaxBlendedQuery(terms, boosts, 1.0f);
Query actual = MultiMatchQuery.blendTerm(
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }),
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null),
new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
@ -174,14 +171,14 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
expectedDisjunct1
), 1.0f);
Query actual = MultiMatchQuery.blendTerm(
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }),
indexService.newQueryShardContext(randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null),
new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
public void testMultiMatchPrefixWithAllField() throws IOException {
QueryShardContext queryShardContext = indexService.newQueryShardContext(
randomInt(20), null, () -> { throw new UnsupportedOperationException(); });
randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null);
queryShardContext.setAllowUnmappedFields(true);
Query parsedQuery =
multiMatchQuery("foo").field("_all").type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX).toQuery(queryShardContext);
@ -191,7 +188,7 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
public void testMultiMatchCrossFieldsWithSynonyms() throws IOException {
QueryShardContext queryShardContext = indexService.newQueryShardContext(
randomInt(20), null, () -> { throw new UnsupportedOperationException(); });
randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null);
// check that synonym query is used for a single field
Query parsedQuery =

View File

@ -32,7 +32,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
@ -297,7 +296,7 @@ public class NestedHelperTests extends ESSingleNodeTestCase {
}
public void testNested() throws IOException {
QueryShardContext context = indexService.newQueryShardContext(0, new MultiReader(), () -> 0);
QueryShardContext context = indexService.newQueryShardContext(0, new MultiReader(), () -> 0, null);
NestedQueryBuilder queryBuilder = new NestedQueryBuilder("nested1", new MatchAllQueryBuilder(), ScoreMode.Avg);
ESToParentBlockJoinQuery query = (ESToParentBlockJoinQuery) queryBuilder.toQuery(context);

View File

@ -99,7 +99,7 @@ public class ExtendedBoundsTests extends ESTestCase {
SearchContext context = mock(SearchContext.class);
QueryShardContext qsc = new QueryShardContext(0,
new IndexSettings(IndexMetaData.builder("foo").settings(indexSettings).build(), indexSettings), null, null, null, null,
null, xContentRegistry(), null, null, () -> now);
null, xContentRegistry(), null, null, () -> now, null);
when(context.getQueryShardContext()).thenReturn(qsc);
FormatDateTimeFormatter formatter = Joda.forPattern("dateOptionalTime");
DocValueFormat format = new DocValueFormat.DateTime(formatter, DateTimeZone.UTC);

View File

@ -33,7 +33,6 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.script.MockScriptEngine;
import org.elasticsearch.script.ScoreAccessor;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptEngine;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.script.ScriptService;
@ -200,6 +199,6 @@ public class ScriptedMetricAggregatorTests extends AggregatorTestCase {
Map<String, ScriptEngine> engines = Collections.singletonMap(scriptEngine.getType(), scriptEngine);
ScriptService scriptService = new ScriptService(Settings.EMPTY, engines, ScriptModule.CORE_CONTEXTS);
return new QueryShardContext(0, mapperService.getIndexSettings(), null, null, mapperService, null, scriptService,
xContentRegistry(), null, null, System::currentTimeMillis);
xContentRegistry(), null, null, System::currentTimeMillis, null);
}
}

View File

@ -41,7 +41,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Bytes> config = ValuesSourceConfig.resolve(
context, null, "bytes", null, null, null, null);
@ -63,7 +63,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Bytes> config = ValuesSourceConfig.resolve(
context, null, "bytes", null, null, null, null);
@ -90,7 +90,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Bytes> config = ValuesSourceConfig.resolve(
context, ValueType.STRING, "bytes", null, null, null, null);
ValuesSource.Bytes valuesSource = config.toValuesSource(context);
@ -116,7 +116,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Numeric> config = ValuesSourceConfig.resolve(
context, null, "long", null, null, null, null);
@ -138,7 +138,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Numeric> config = ValuesSourceConfig.resolve(
context, null, "long", null, null, null, null);
@ -165,7 +165,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Numeric> config = ValuesSourceConfig.resolve(
context, ValueType.NUMBER, "long", null, null, null, null);
@ -192,7 +192,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Numeric> config = ValuesSourceConfig.resolve(
context, null, "bool", null, null, null, null);
@ -214,7 +214,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Numeric> config = ValuesSourceConfig.resolve(
context, null, "bool", null, null, null, null);
@ -241,7 +241,7 @@ public class ValuesSourceConfigTests extends ESSingleNodeTestCase {
.get();
try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L);
QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null);
ValuesSourceConfig<ValuesSource.Numeric> config = ValuesSourceConfig.resolve(
context, ValueType.BOOLEAN, "bool", null, null, null, null);

View File

@ -136,7 +136,7 @@ public class FetchSourceSubPhaseTests extends ESTestCase {
@Override
public SearchLookup lookup() {
SearchLookup lookup = new SearchLookup(this.mapperService(), this.fieldData(), null);
SearchLookup lookup = new SearchLookup(this.mapperService(), this::getForField, null);
lookup.source().setSource(source);
return lookup;
}

View File

@ -273,7 +273,7 @@ public class HighlightBuilderTests extends ESTestCase {
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(index, indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in highlighter
QueryShardContext mockShardContext = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(),
null, null, System::currentTimeMillis) {
null, null, System::currentTimeMillis, null) {
@Override
public MappedFieldType fieldMapper(String name) {
TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name);

View File

@ -137,7 +137,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in query rescorer
QueryShardContext mockShardContext = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(),
null, null, () -> nowInMillis) {
null, null, () -> nowInMillis, null) {
@Override
public MappedFieldType fieldMapper(String name) {
TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name);

View File

@ -190,8 +190,8 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
}
});
long nowInMillis = randomNonNegativeLong();
return new QueryShardContext(0, idxSettings, bitsetFilterCache, ifds, null, null, scriptService,
xContentRegistry(), null, null, () -> nowInMillis) {
return new QueryShardContext(0, idxSettings, bitsetFilterCache, ifds::getForField, null, null, scriptService,
xContentRegistry(), null, null, () -> nowInMillis, null) {
@Override
public MappedFieldType fieldMapper(String name) {
return provideMappedFieldType(name);

View File

@ -178,7 +178,7 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui
when(scriptService.compile(any(Script.class), any())).then(invocation -> new TestTemplateService.MockTemplateScript.Factory(
((Script) invocation.getArguments()[0]).getIdOrCode()));
QueryShardContext mockShardContext = new QueryShardContext(0, idxSettings, null, null, mapperService, null, scriptService,
xContentRegistry(), null, null, System::currentTimeMillis);
xContentRegistry(), null, null, System::currentTimeMillis, null);
SuggestionContext suggestionContext = suggestionBuilder.build(mockShardContext);
assertEquals(toBytesRef(suggestionBuilder.text()), suggestionContext.getText());

View File

@ -270,7 +270,7 @@ public abstract class MultiValuesSourceAggregationBuilder<VS extends ValuesSourc
return config.unmapped(true);
}
IndexFieldData<?> indexFieldData = context.fieldData().getForField(fieldType);
IndexFieldData<?> indexFieldData = context.getForField(fieldType);
ValuesSourceConfig<VS> config;
if (valuesSourceType == ValuesSourceType.ANY) {

View File

@ -186,7 +186,7 @@ public class ExpressionScriptEngine extends AbstractComponent implements ScriptE
throw new ParseException("Field [" + fieldname + "] does not exist in mappings", 5);
}
IndexFieldData<?> fieldData = lookup.doc().fieldDataService().getForField(fieldType);
IndexFieldData<?> fieldData = lookup.doc().getForField(fieldType);
// delegate valuesource creation based on field's type
// there are three types of "fields" to expressions, and each one has a different "api" of variables and methods.

View File

@ -38,7 +38,7 @@ public class ExpressionTests extends ESSingleNodeTestCase {
super.setUp();
IndexService index = createIndex("test", Settings.EMPTY, "type", "d", "type=double");
service = new ExpressionScriptEngine(Settings.EMPTY);
lookup = new SearchLookup(index.mapperService(), index.fieldData(), null);
lookup = new SearchLookup(index.mapperService(), index.fieldData()::getForField, null);
}
private SearchScript.LeafFactory compile(String expression) {

View File

@ -40,7 +40,7 @@ public class NeedsScoreTests extends ESSingleNodeTestCase {
PainlessScriptEngine service = new PainlessScriptEngine(Settings.EMPTY,
Arrays.asList(SearchScript.CONTEXT, ExecutableScript.CONTEXT));
SearchLookup lookup = new SearchLookup(index.mapperService(), index.fieldData(), null);
SearchLookup lookup = new SearchLookup(index.mapperService(), index.fieldData()::getForField, null);
SearchScript.Factory factory = service.compile(null, "1.2", SearchScript.CONTEXT, Collections.emptyMap());
SearchScript.LeafFactory ss = factory.newFactory(Collections.emptyMap(), lookup);

View File

@ -108,7 +108,7 @@ public class ChildrenAggregationBuilder
parentFilter = parentIdFieldMapper.getParentFilter();
childFilter = parentIdFieldMapper.getChildFilter(childType);
MappedFieldType fieldType = parentIdFieldMapper.fieldType();
final SortedSetDVOrdinalsIndexFieldData fieldData = context.fieldData().getForField(fieldType);
final SortedSetDVOrdinalsIndexFieldData fieldData = context.getForField(fieldType);
config.fieldContext(new FieldContext(fieldType.name(), fieldData, fieldType));
} else {
config.unmapped(true);
@ -128,7 +128,7 @@ public class ChildrenAggregationBuilder
parentFilter = parentDocMapper.typeFilter(context.getQueryShardContext());
childFilter = childDocMapper.typeFilter(context.getQueryShardContext());
MappedFieldType parentFieldType = parentDocMapper.parentFieldMapper().getParentJoinFieldType();
final SortedSetDVOrdinalsIndexFieldData fieldData = context.fieldData().getForField(parentFieldType);
final SortedSetDVOrdinalsIndexFieldData fieldData = context.getForField(parentFieldType);
config.fieldContext(new FieldContext(parentFieldType.name(), fieldData,
parentFieldType));
} else {

View File

@ -314,7 +314,7 @@ public class PercolatorFieldMapperTests extends ESSingleNodeTestCase {
QueryShardContext shardContext = indexService.newQueryShardContext(
randomInt(20), null, () -> {
throw new UnsupportedOperationException();
});
}, null);
PlainActionFuture<QueryBuilder> future = new PlainActionFuture<>();
Rewriteable.rewriteAndFetch(queryBuilder, shardContext, future);
assertQueryBuilder(qbSource, future.get());

View File

@ -58,7 +58,7 @@ public class Murmur3FieldMapperTests extends ESSingleNodeTestCase {
Collections.singletonMap(Murmur3FieldMapper.CONTENT_TYPE, new Murmur3FieldMapper.TypeParser()),
Collections.emptyMap());
Supplier<QueryShardContext> queryShardContext = () -> {
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); });
return indexService.newQueryShardContext(0, null, () -> { throw new UnsupportedOperationException(); }, null);
};
parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(), indexService.getIndexAnalyzers(),
indexService.xContentRegistry(), indexService.similarityService(), mapperRegistry, queryShardContext);

View File

@ -1,5 +1,5 @@
---
"Test that remote index names are preserved in top hits":
setup:
- do:
indices.create:
@ -9,6 +9,16 @@
index:
number_of_shards: 1
number_of_replicas: 0
---
teardown:
- do:
indices.delete:
index: single_doc_index
ignore_unavailable: true
---
"Test that remote index names are preserved in top hits":
- do:
bulk:

View File

@ -0,0 +1,52 @@
---
setup:
- do:
indices.create:
index: single_doc_index
body:
settings:
index:
number_of_shards: 1
number_of_replicas: 0
---
teardown:
- do:
indices.delete:
index: single_doc_index
ignore_unavailable: true
---
"Test that remote indices are maintained when we aggregate on _index":
- do:
bulk:
refresh: true
body:
- '{"index": {"_index": "single_doc_index", "_type": "test_type"}}'
- '{"f1": "local_cluster", "sort_field": 0}'
- do:
search:
index: "single_doc_index,my_remote_cluster:single_doc_index"
body:
sort: "sort_field"
aggs:
idx_terms:
terms:
field: "_index"
- match: { hits.total: 2 }
- match: { hits.hits.0._index: "single_doc_index"}
- match: { hits.hits.1._index: "my_remote_cluster:single_doc_index"}
- match: { hits.total: 2 }
- match: { _shards.total: 2 }
- match: { _shards.successful: 2 }
- match: { _shards.skipped : 0}
- match: { _shards.failed: 0 }
- length: { aggregations.idx_terms.buckets: 2 }
- match: { aggregations.idx_terms.buckets.0.key: "my_remote_cluster:single_doc_index" }
- match: { aggregations.idx_terms.buckets.0.doc_count: 1 }
- match: { aggregations.idx_terms.buckets.1.key: "single_doc_index" }
- match: { aggregations.idx_terms.buckets.1.doc_count: 1 }

View File

@ -44,6 +44,7 @@ import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache.Listener;
import org.elasticsearch.index.cache.query.DisabledQueryCache;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.ContentPath;
@ -68,6 +69,8 @@ import org.elasticsearch.search.lookup.SearchLookup;
import org.elasticsearch.test.ESTestCase;
import org.junit.After;
import org.mockito.Matchers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.IOException;
import java.util.ArrayList;
@ -106,9 +109,14 @@ public abstract class AggregatorTestCase extends ESTestCase {
IndexFieldDataService ifds = new IndexFieldDataService(indexSettings,
new IndicesFieldDataCache(Settings.EMPTY, new IndexFieldDataCache.Listener() {
}), circuitBreakerService, mapperService);
when(searchContext.fieldData()).thenReturn(ifds);
when(searchContext.getForField(Mockito.any(MappedFieldType.class))).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
return ifds.getForField((MappedFieldType) invocationOnMock.getArguments()[0]);
}
});
SearchLookup searchLookup = new SearchLookup(mapperService, ifds, new String[]{"type"});
SearchLookup searchLookup = new SearchLookup(mapperService, ifds::getForField, new String[]{"type"});
when(searchContext.lookup()).thenReturn(searchLookup);
QueryShardContext queryShardContext = queryShardContextMock(mapperService, fieldTypes, circuitBreakerService);

View File

@ -68,8 +68,10 @@ import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.IndexAnalyzers;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
@ -117,7 +119,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Stream;
@ -221,9 +222,10 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}
@Override
public IndexFieldDataService fieldData() {
return serviceHolder.indexFieldDataService; // need to build / parse inner hits sort fields
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
return serviceHolder.indexFieldDataService.getForField(fieldType); // need to build / parse inner hits sort fields
}
};
testSearchContext.getQueryShardContext().setTypes(types);
return testSearchContext;
@ -1075,8 +1077,8 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}
QueryShardContext createShardContext() {
return new QueryShardContext(0, idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService,
scriptService, xContentRegistry, this.client, null, () -> nowInMillis);
return new QueryShardContext(0, idxSettings, bitsetFilterCache, indexFieldDataService::getForField, mapperService,
similarityService, scriptService, xContentRegistry, this.client, null, () -> nowInMillis, null);
}
ScriptModule createScriptModule(List<ScriptPlugin> scriptPlugins) {

View File

@ -31,6 +31,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
@ -104,7 +105,7 @@ public class TestSearchContext extends SearchContext {
this.fixedBitSetFilterCache = indexService.cache().bitsetFilterCache();
this.threadPool = threadPool;
this.indexShard = indexService.getShardOrNull(0);
queryShardContext = indexService.newQueryShardContext(0, null, () -> 0L);
queryShardContext = indexService.newQueryShardContext(0, null, () -> 0L, null);
}
public TestSearchContext(QueryShardContext queryShardContext) {
@ -307,8 +308,8 @@ public class TestSearchContext extends SearchContext {
}
@Override
public IndexFieldDataService fieldData() {
return indexFieldDataService;
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
return indexFieldDataService.getForField(fieldType);
}
@Override

View File

@ -41,7 +41,7 @@ public class MockSearchServiceTests extends ESTestCase {
final long nowInMillis = randomNonNegativeLong();
SearchContext s = new TestSearchContext(new QueryShardContext(0,
new IndexSettings(EMPTY_INDEX_METADATA, Settings.EMPTY), null, null, null, null, null, xContentRegistry(),
null, null, () -> nowInMillis)) {
null, null, () -> nowInMillis, null)) {
@Override
public SearchShardTarget shardTarget() {