Fix AnalysisMode propagation in NamedAnalyzer (#44626)
NamedAnalyzer should return the same AnalysisMode than any custom analyzer it wraps, otherwise AnalysisMode.ALL. This used to be only CustomAnalyzer in the past, but with the introduction of the ReloadableCustomAnalyzer this needs to be added as an option where the analysis mode gets propagated. Closes #44625
This commit is contained in:
parent
c3b6ab4dec
commit
eafe54c81c
|
@ -53,8 +53,8 @@ public class NamedAnalyzer extends DelegatingAnalyzerWrapper {
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.analyzer = analyzer;
|
this.analyzer = analyzer;
|
||||||
this.positionIncrementGap = positionIncrementGap;
|
this.positionIncrementGap = positionIncrementGap;
|
||||||
if (analyzer instanceof org.elasticsearch.index.analysis.CustomAnalyzer) {
|
if (analyzer instanceof org.elasticsearch.index.analysis.AnalyzerComponentsProvider) {
|
||||||
this.analysisMode = ((org.elasticsearch.index.analysis.CustomAnalyzer) analyzer).getAnalysisMode();
|
this.analysisMode = ((org.elasticsearch.index.analysis.AnalyzerComponentsProvider) analyzer).getComponents().analysisMode();
|
||||||
} else {
|
} else {
|
||||||
this.analysisMode = AnalysisMode.ALL;
|
this.analysisMode = AnalysisMode.ALL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.analysis;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.elasticsearch.index.mapper.MapperException;
|
import org.elasticsearch.index.mapper.MapperException;
|
||||||
|
import org.elasticsearch.index.mapper.TextFieldMapper;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
public class NamedAnalyzerTests extends ESTestCase {
|
public class NamedAnalyzerTests extends ESTestCase {
|
||||||
|
@ -73,7 +74,13 @@ public class NamedAnalyzerTests extends ESTestCase {
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new CustomAnalyzer(null, new CharFilterFactory[0],
|
TokenFilterFactory[] tokenfilters = new TokenFilterFactory[] { tokenFilter };
|
||||||
new TokenFilterFactory[] { tokenFilter });
|
CharFilterFactory[] charFilters = new CharFilterFactory[0];
|
||||||
|
if (mode == AnalysisMode.SEARCH_TIME && randomBoolean()) {
|
||||||
|
AnalyzerComponents components = new AnalyzerComponents(null, charFilters, tokenfilters);
|
||||||
|
// sometimes also return reloadable custom analyzer
|
||||||
|
return new ReloadableCustomAnalyzer(components , TextFieldMapper.Defaults.POSITION_INCREMENT_GAP, -1);
|
||||||
|
}
|
||||||
|
return new CustomAnalyzer(null, charFilters, tokenfilters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction.Response;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.analysis.common.CommonAnalysisPlugin;
|
import org.elasticsearch.analysis.common.CommonAnalysisPlugin;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.index.mapper.MapperException;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||||
|
@ -104,4 +105,38 @@ public class ReloadSynonymAnalyzerTests extends ESSingleNodeTestCase {
|
||||||
response = client().prepareSearch(indexName).setQuery(QueryBuilders.matchQuery("field", "buzz")).get();
|
response = client().prepareSearch(indexName).setQuery(QueryBuilders.matchQuery("field", "buzz")).get();
|
||||||
assertHitCount(response, 1L);
|
assertHitCount(response, 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testUpdateableSynonymsRejectedAtIndexTime() throws FileNotFoundException, IOException {
|
||||||
|
String synonymsFileName = "synonyms.txt";
|
||||||
|
Path configDir = node().getEnvironment().configFile();
|
||||||
|
if (Files.exists(configDir) == false) {
|
||||||
|
Files.createDirectory(configDir);
|
||||||
|
}
|
||||||
|
Path synonymsFile = configDir.resolve(synonymsFileName);
|
||||||
|
if (Files.exists(synonymsFile) == false) {
|
||||||
|
Files.createFile(synonymsFile);
|
||||||
|
}
|
||||||
|
try (PrintWriter out = new PrintWriter(
|
||||||
|
new OutputStreamWriter(Files.newOutputStream(synonymsFile, StandardOpenOption.WRITE), StandardCharsets.UTF_8))) {
|
||||||
|
out.println("foo, baz");
|
||||||
|
}
|
||||||
|
|
||||||
|
final String indexName = "test";
|
||||||
|
final String analyzerName = "my_synonym_analyzer";
|
||||||
|
MapperException ex = expectThrows(MapperException.class, () -> client().admin().indices().prepareCreate(indexName)
|
||||||
|
.setSettings(Settings.builder()
|
||||||
|
.put("index.number_of_shards", 5)
|
||||||
|
.put("index.number_of_replicas", 0)
|
||||||
|
.put("analysis.analyzer." + analyzerName + ".tokenizer", "standard")
|
||||||
|
.putList("analysis.analyzer." + analyzerName + ".filter", "lowercase", "my_synonym_filter")
|
||||||
|
.put("analysis.filter.my_synonym_filter.type", "synonym")
|
||||||
|
.put("analysis.filter.my_synonym_filter.updateable", "true")
|
||||||
|
.put("analysis.filter.my_synonym_filter.synonyms_path", synonymsFileName))
|
||||||
|
.addMapping("_doc", "field", "type=text,analyzer=" + analyzerName).get());
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"Failed to parse mapping [_doc]: analyzer [my_synonym_analyzer] "
|
||||||
|
+ "contains filters [my_synonym_filter] that are not allowed to run in all mode.",
|
||||||
|
ex.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue