Skip to content

Commit

Permalink
Make IndexAnalyzers an interface (#94819)
Browse files Browse the repository at this point in the history
IndexAnalyzers is currently always a concrete class wrapping several
Maps of NamedAnalyzers. This means that whenever it is used it needs
to instantiate all of its component analyzers, making testing much heavier
than it needs to be. It also means that things like overriding analysis for
legacy indexes is pushed into mapper parameters, rather than being
handled in a single place.

This commit makes IndexAnalyzers into an interface, with an anonymous
concrete implementation that handles reloading and closing for index
shards.
  • Loading branch information
romseygeek committed Mar 28, 2023
1 parent 38645b6 commit 35da972
Show file tree
Hide file tree
Showing 31 changed files with 176 additions and 243 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ public static MapperService create(String mappings) {
SimilarityService similarityService = new SimilarityService(indexSettings, null, Map.of());
MapperService mapperService = new MapperService(
indexSettings,
new IndexAnalyzers(
IndexAnalyzers.of(
Map.of("default", new NamedAnalyzer("default", AnalyzerScope.INDEX, new StandardAnalyzer())),
Map.of("lowercase", new NamedAnalyzer("lowercase", AnalyzerScope.INDEX, new LowercaseNormalizer())),
Map.of()
Map.of("lowercase", new NamedAnalyzer("lowercase", AnalyzerScope.INDEX, new LowercaseNormalizer()))
),
XContentParserConfiguration.EMPTY.withRegistry(new NamedXContentRegistry(ClusterModule.getNamedXWriteables()))
.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
package org.elasticsearch.benchmark.search;

import org.apache.logging.log4j.util.Strings;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
Expand All @@ -23,13 +22,11 @@
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.core.IOUtils;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AnalyzerScope;
import org.elasticsearch.index.analysis.IndexAnalyzers;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
import org.elasticsearch.index.mapper.MapperRegistry;
import org.elasticsearch.index.mapper.MapperService;
Expand Down Expand Up @@ -173,11 +170,7 @@ protected final MapperService createMapperService(String mappings) {
SimilarityService similarityService = new SimilarityService(indexSettings, null, Map.of());
MapperService mapperService = new MapperService(
indexSettings,
new IndexAnalyzers(
Map.of("default", new NamedAnalyzer("default", AnalyzerScope.INDEX, new StandardAnalyzer())),
Map.of(),
Map.of()
),
(type, name) -> Lucene.STANDARD_ANALYZER,
XContentParserConfiguration.EMPTY.withRegistry(new NamedXContentRegistry(ClusterModule.getNamedXWriteables()))
.withDeprecationHandler(LoggingDeprecationHandler.INSTANCE),
similarityService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,8 @@ protected IndexAnalyzers createIndexAnalyzers(IndexSettings indexSettings) {
NamedAnalyzer keyword = new NamedAnalyzer("keyword", AnalyzerScope.INDEX, new KeywordAnalyzer());
NamedAnalyzer simple = new NamedAnalyzer("simple", AnalyzerScope.INDEX, new SimpleAnalyzer());
NamedAnalyzer whitespace = new NamedAnalyzer("whitespace", AnalyzerScope.INDEX, new WhitespaceAnalyzer());
return new IndexAnalyzers(
Map.of("default", dflt, "standard", standard, "keyword", keyword, "simple", simple, "whitespace", whitespace),
Map.of(),
Map.of()
return IndexAnalyzers.of(
Map.of("default", dflt, "standard", standard, "keyword", keyword, "simple", simple, "whitespace", whitespace)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ protected IndexAnalyzers createIndexAnalyzers(IndexSettings indexSettings) {
NamedAnalyzer dflt = new NamedAnalyzer("default", AnalyzerScope.INDEX, new StandardAnalyzer());
NamedAnalyzer standard = new NamedAnalyzer("standard", AnalyzerScope.INDEX, new StandardAnalyzer());
NamedAnalyzer keyword = new NamedAnalyzer("keyword", AnalyzerScope.INDEX, new KeywordAnalyzer());
return new IndexAnalyzers(Map.of("default", dflt, "standard", standard, "keyword", keyword), Map.of(), Map.of());
return IndexAnalyzers.of(Map.of("default", dflt, "standard", standard, "keyword", keyword));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,8 @@ public TokenStream create(TokenStream tokenStream) {
} }
)
);
return new IndexAnalyzers(
Map.of("default", dflt, "standard", standard, "keyword", keyword, "whitespace", whitespace, "my_stop_analyzer", stop),
Map.of(),
Map.of()
return IndexAnalyzers.of(
Map.of("default", dflt, "standard", standard, "keyword", keyword, "whitespace", whitespace, "my_stop_analyzer", stop)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AnalyzerScope;
import org.elasticsearch.index.analysis.IndexAnalyzers;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.MapperRegistry;
import org.elasticsearch.index.mapper.MapperService;
Expand Down Expand Up @@ -140,9 +139,7 @@ private void checkMappingsCompatibility(IndexMetadata indexMetadata) {

IndexSettings indexSettings = new IndexSettings(indexMetadata, this.settings);

final Map<String, TriFunction<Settings, Version, ScriptService, Similarity>> similarityMap = new AbstractMap<
String,
TriFunction<Settings, Version, ScriptService, Similarity>>() {
final Map<String, TriFunction<Settings, Version, ScriptService, Similarity>> similarityMap = new AbstractMap<>() {
@Override
public boolean containsKey(Object key) {
return true;
Expand All @@ -169,33 +166,21 @@ protected TokenStreamComponents createComponents(String fieldName) {
}
});

final Map<String, NamedAnalyzer> analyzerMap = new AbstractMap<String, NamedAnalyzer>() {
@Override
public NamedAnalyzer get(Object key) {
assert key instanceof String : "key must be a string but was: " + key.getClass();
return new NamedAnalyzer((String) key, AnalyzerScope.INDEX, fakeDefault.analyzer());
}

// this entrySet impl isn't fully correct but necessary as IndexAnalyzers will iterate
// over all analyzers to close them
@Override
public Set<Entry<String, NamedAnalyzer>> entrySet() {
return Collections.emptySet();
}
};
try (IndexAnalyzers fakeIndexAnalzyers = new IndexAnalyzers(analyzerMap, analyzerMap, analyzerMap)) {
try (
MapperService mapperService = new MapperService(
indexSettings,
fakeIndexAnalzyers,
(type, name) -> new NamedAnalyzer(name, AnalyzerScope.INDEX, fakeDefault.analyzer()),
parserConfiguration,
similarityService,
mapperRegistry,
() -> null,
indexSettings.getMode().idFieldMapperWithoutFieldData(),
scriptService
);
)
) {
mapperService.merge(indexMetadata, MapperService.MergeReason.MAPPING_RECOVERY);
}

} catch (Exception ex) {
// Wrap the inner exception so we have the index name in the exception message
throw new IllegalStateException("Failed to parse mappings for index [" + indexMetadata.getIndex() + "]", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public class IndexService extends AbstractIndexComponent implements IndicesClust
private final AtomicBoolean closed = new AtomicBoolean(false);
private final AtomicBoolean deleted = new AtomicBoolean(false);
private final IndexSettings indexSettings;
private final IndexAnalyzers indexAnalyzers;
private final List<SearchOperationListener> searchOperationListeners;
private final List<IndexingOperationListener> indexingOperationListeners;
private final BooleanSupplier allowExpensiveQueries;
Expand Down Expand Up @@ -192,6 +193,7 @@ public IndexService(
this.expressionResolver = expressionResolver;
this.valuesSourceRegistry = valuesSourceRegistry;
this.snapshotCommitSupplier = snapshotCommitSupplier;
this.indexAnalyzers = indexAnalyzers;
if (needsMapperService(indexSettings, indexCreationContext)) {
assert indexAnalyzers != null;
this.mapperService = new MapperService(
Expand Down Expand Up @@ -357,7 +359,7 @@ public synchronized void close(final String reason, boolean delete) throws IOExc
bitsetFilterCache,
indexCache,
indexFieldData,
mapperService,
indexAnalyzers,
refreshTask,
fsyncTask,
trimTranslogTask,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
Expand Down Expand Up @@ -649,6 +650,10 @@ public static IndexAnalyzers build(
throw new IllegalArgumentException("no default analyzer configured");
}
defaultAnalyzer.checkAllowedInMode(AnalysisMode.ALL);
assert Objects.equals(defaultAnalyzer.name(), DEFAULT_ANALYZER_NAME);
if (Objects.equals(defaultAnalyzer.name(), DEFAULT_ANALYZER_NAME) == false) {
throw new IllegalStateException("default analyzer must have the name [default] but was: [" + defaultAnalyzer.name() + "]");
}

if (analyzers.containsKey("default_index")) {
throw new IllegalArgumentException(
Expand All @@ -664,7 +669,7 @@ public static IndexAnalyzers build(
throw new IllegalArgumentException("analyzer name must not start with '_'. got \"" + analyzer.getKey() + "\"");
}
}
return new IndexAnalyzers(analyzers, normalizers, whitespaceNormalizers);
return IndexAnalyzers.of(analyzers, normalizers, whitespaceNormalizers);
}

private static NamedAnalyzer produceAnalyzer(
Expand Down

0 comments on commit 35da972

Please sign in to comment.