Skip to content

Commit 9a572a7

Browse files
authored
Merge pull request #53 from wyhw/master
support for Elasticsearch 7.3.1
2 parents c219044 + c7ac0cc commit 9a572a7

File tree

4 files changed

+103
-128
lines changed

4 files changed

+103
-128
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
<groupId>com.bellszhu.elasticsearch</groupId>
66
<artifactId>elasticsearch-analysis-dynamic-synonym</artifactId>
7-
<version>7.0.0</version>
7+
<version>7.3.1</version>
88
<packaging>jar</packaging>
99
<name>elasticsearch-dynamic-synonym</name>
1010
<description>Analysis-plugin for synonym</description>
1111

1212
<properties>
1313
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1414
<elasticsearch.version>${project.version}</elasticsearch.version>
15-
<maven.compiler.target>1.8</maven.compiler.target>
15+
<maven.compiler.target>12</maven.compiler.target>
1616
<elasticsearch.plugin.name>analysis-dynamic-synonym</elasticsearch.plugin.name>
1717
<elasticsearch.assembly.descriptor>${project.basedir}/src/main/assemblies/plugin.xml
1818
</elasticsearch.assembly.descriptor>

src/main/java/com/bellszhu/elasticsearch/plugin/DynamicSynonymPlugin.java

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package com.bellszhu.elasticsearch.plugin;
55

66
import com.bellszhu.elasticsearch.plugin.synonym.analysis.DynamicSynonymTokenFilterFactory;
7-
import com.bellszhu.elasticsearch.plugin.synonym.service.DynamicSynonymAnalysisService;
87
import org.elasticsearch.client.Client;
98
import org.elasticsearch.cluster.service.ClusterService;
109
import org.elasticsearch.common.component.LifecycleComponent;
@@ -14,7 +13,6 @@
1413
import org.elasticsearch.env.Environment;
1514
import org.elasticsearch.env.NodeEnvironment;
1615
import org.elasticsearch.index.IndexSettings;
17-
import org.elasticsearch.index.analysis.AnalysisRegistry;
1816
import org.elasticsearch.index.analysis.TokenFilterFactory;
1917
import org.elasticsearch.indices.analysis.AnalysisModule;
2018
import org.elasticsearch.plugins.AnalysisPlugin;
@@ -30,65 +28,18 @@
3028
import java.util.Map;
3129

3230
import static java.util.Collections.singletonList;
31+
import static org.elasticsearch.plugins.AnalysisPlugin.requiresAnalysisSettings;
32+
3333

3434
/**
3535
* @author bellszhu
3636
*/
3737
public class DynamicSynonymPlugin extends Plugin implements AnalysisPlugin {
38-
private PluginComponent pluginComponent = new PluginComponent();
39-
40-
@Override
41-
public Collection<Object> createComponents(Client client,
42-
ClusterService clusterService,
43-
ThreadPool threadPool,
44-
ResourceWatcherService resourceWatcherService,
45-
ScriptService scriptService,
46-
NamedXContentRegistry xContentRegistry,
47-
Environment environment,
48-
NodeEnvironment nodeEnvironment,
49-
NamedWriteableRegistry namedWriteableRegistry) {
50-
Collection<Object> components = new ArrayList<>();
51-
components.add(pluginComponent);
52-
return components;
53-
}
54-
55-
@Override
56-
public Collection<Class<? extends LifecycleComponent>> getGuiceServiceClasses() {
57-
return singletonList(DynamicSynonymAnalysisService.class);
58-
}
5938

6039
@Override
6140
public Map<String, AnalysisModule.AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
62-
Map<String, AnalysisModule.AnalysisProvider<org.elasticsearch.index.analysis.TokenFilterFactory>> extra = new HashMap<>();
63-
64-
extra.put("dynamic_synonym", new AnalysisModule.AnalysisProvider<TokenFilterFactory>() {
65-
66-
@Override
67-
public TokenFilterFactory get(IndexSettings indexSettings, Environment environment, String name, Settings settings)
68-
throws IOException {
69-
return new DynamicSynonymTokenFilterFactory(indexSettings, environment, name, settings, pluginComponent.getAnalysisRegistry());
70-
}
71-
72-
@Override
73-
public boolean requiresAnalysisSettings() {
74-
return true;
75-
}
76-
});
41+
Map<String, AnalysisModule.AnalysisProvider<TokenFilterFactory>> extra = new HashMap<>();
42+
extra.put("dynamic_synonym", requiresAnalysisSettings(DynamicSynonymTokenFilterFactory::new));
7743
return extra;
7844
}
79-
80-
81-
public static class PluginComponent {
82-
83-
private AnalysisRegistry analysisRegistry;
84-
85-
AnalysisRegistry getAnalysisRegistry() {
86-
return analysisRegistry;
87-
}
88-
89-
public void setAnalysisRegistry(AnalysisRegistry analysisRegistry) {
90-
this.analysisRegistry = analysisRegistry;
91-
}
92-
93-
}
9445
}

src/main/java/com/bellszhu/elasticsearch/plugin/synonym/analysis/DynamicSynonymTokenFilterFactory.java

Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
import org.apache.lucene.analysis.core.LowerCaseFilter;
1010
import org.apache.lucene.analysis.core.WhitespaceTokenizer;
1111
import org.apache.lucene.analysis.synonym.SynonymMap;
12+
import org.elasticsearch.common.logging.DeprecationLogger;
1213
import org.elasticsearch.common.settings.Settings;
1314
import org.elasticsearch.env.Environment;
1415
import org.elasticsearch.index.IndexSettings;
1516
import org.elasticsearch.index.analysis.AbstractTokenFilterFactory;
16-
import org.elasticsearch.index.analysis.AnalysisRegistry;
17+
import org.elasticsearch.index.analysis.Analysis;
18+
import org.elasticsearch.index.analysis.AnalysisMode;
19+
import org.elasticsearch.index.analysis.CharFilterFactory;
20+
import org.elasticsearch.index.analysis.CustomAnalyzer;
21+
import org.elasticsearch.index.analysis.TokenFilterFactory;
1722
import org.elasticsearch.index.analysis.TokenizerFactory;
18-
import org.elasticsearch.indices.analysis.AnalysisModule;
1923

2024
import java.io.IOException;
2125
import java.util.Map;
@@ -26,12 +30,18 @@
2630
import java.util.concurrent.TimeUnit;
2731
import java.util.concurrent.atomic.AtomicInteger;
2832

33+
import java.util.List;
34+
import java.util.function.Function;
35+
2936
/**
3037
* @author bellszhu
3138
*/
3239
public class DynamicSynonymTokenFilterFactory extends
3340
AbstractTokenFilterFactory {
3441

42+
private static final DeprecationLogger DEPRECATION_LOGGER
43+
= new DeprecationLogger(LogManager.getLogger(DynamicSynonymTokenFilterFactory.class));
44+
3545
/**
3646
* Static id generator
3747
*/
@@ -43,20 +53,21 @@ public class DynamicSynonymTokenFilterFactory extends
4353
return thread;
4454
});
4555
private final String location;
46-
private final boolean ignoreCase;
4756
private final boolean expand;
57+
private final boolean lenient;
4858
private final String format;
4959
private final int interval;
5060
private volatile ScheduledFuture<?> scheduledFuture;
5161
private SynonymMap synonymMap;
5262
private Map<DynamicSynonymFilter, Integer> dynamicSynonymFilters = new WeakHashMap<>();
63+
protected final Environment environment;
64+
protected final AnalysisMode analysisMode;
5365

5466
public DynamicSynonymTokenFilterFactory(
5567
IndexSettings indexSettings,
5668
Environment env,
5769
String name,
58-
Settings settings,
59-
AnalysisRegistry analysisRegistry
70+
Settings settings
6071
) throws IOException {
6172

6273
super(indexSettings, name, settings);
@@ -68,58 +79,103 @@ public DynamicSynonymTokenFilterFactory(
6879
}
6980

7081
this.interval = settings.getAsInt("interval", 60);
71-
this.ignoreCase = settings.getAsBoolean("ignore_case", false);
82+
if (settings.get("ignore_case") != null) {
83+
DEPRECATION_LOGGER.deprecated(
84+
"The ignore_case option on the synonym_graph filter is deprecated. " +
85+
"Instead, insert a lowercase filter in the filter chain before the synonym_graph filter.");
86+
}
7287
this.expand = settings.getAsBoolean("expand", true);
88+
this.lenient = settings.getAsBoolean("lenient", false);
7389
this.format = settings.get("format", "");
90+
boolean updateable = settings.getAsBoolean("updateable", false);
91+
this.analysisMode = updateable ? AnalysisMode.SEARCH_TIME : AnalysisMode.ALL;
92+
this.environment = env;
93+
}
7494

75-
String tokenizerName = settings.get("tokenizer", "whitespace");
76-
77-
AnalysisModule.AnalysisProvider<TokenizerFactory> tokenizerFactoryFactory =
78-
analysisRegistry.getTokenizerProvider(tokenizerName, indexSettings);
79-
if (tokenizerFactoryFactory == null) {
80-
throw new IllegalArgumentException("failed to find tokenizer [" + tokenizerName + "] for synonym token filter");
81-
}
82-
final TokenizerFactory tokenizerFactory = tokenizerFactoryFactory.get(indexSettings, env, tokenizerName,
95+
@Override
96+
public AnalysisMode getAnalysisMode() {
97+
return this.analysisMode;
98+
}
8399

84-
AnalysisRegistry.getSettingsFromIndexSettings(indexSettings, AnalysisRegistry.INDEX_ANALYSIS_TOKENIZER + "." + tokenizerName));
85100

101+
@Override
102+
public TokenStream create(TokenStream tokenStream) {
103+
throw new IllegalStateException("Call getChainAwareTokenFilterFactory to specialize this factory for an analysis chain first");
104+
}
86105

87-
Analyzer analyzer = new Analyzer() {
106+
public TokenFilterFactory getChainAwareTokenFilterFactory(TokenizerFactory tokenizer, List<CharFilterFactory> charFilters,
107+
List<TokenFilterFactory> previousTokenFilters,
108+
Function<String, TokenFilterFactory> allFilters) {
109+
final Analyzer analyzer = buildSynonymAnalyzer(tokenizer, charFilters, previousTokenFilters, allFilters);
110+
synonymMap = buildSynonyms(analyzer);
111+
final String name = name();
112+
return new TokenFilterFactory() {
88113
@Override
89-
protected TokenStreamComponents createComponents(String fieldName) {
90-
Tokenizer tokenizer = tokenizerFactory == null ? new WhitespaceTokenizer() : tokenizerFactory.create();
91-
TokenStream stream = ignoreCase ? new LowerCaseFilter(tokenizer) : tokenizer;
92-
return new TokenStreamComponents(tokenizer, stream);
114+
public String name() {
115+
return name;
93116
}
94-
};
95117

96-
SynonymFile synonymFile;
97-
if (location.startsWith("http://") || location.startsWith("https://")) {
98-
synonymFile = new RemoteSynonymFile(env, analyzer, expand, format,
99-
location);
100-
} else {
101-
synonymFile = new LocalSynonymFile(env, analyzer, expand, format,
102-
location);
103-
}
104-
synonymMap = synonymFile.reloadSynonymMap();
118+
@Override
119+
public TokenStream create(TokenStream tokenStream) {
120+
// fst is null means no synonyms
121+
if (synonymMap.fst == null) {
122+
return tokenStream;
123+
}
124+
DynamicSynonymFilter dynamicSynonymFilter = new DynamicSynonymFilter(tokenStream, synonymMap, false);
125+
dynamicSynonymFilters.put(dynamicSynonymFilter, 1);
105126

106-
scheduledFuture = pool.scheduleAtFixedRate(new Monitor(synonymFile),
107-
interval, interval, TimeUnit.SECONDS);
127+
return dynamicSynonymFilter;
128+
}
129+
130+
@Override
131+
public TokenFilterFactory getSynonymFilter() {
132+
// In order to allow chained synonym filters, we return IDENTITY here to
133+
// ensure that synonyms don't get applied to the synonym map itself,
134+
// which doesn't support stacked input tokens
135+
return IDENTITY_FILTER;
136+
}
108137

138+
@Override
139+
public AnalysisMode getAnalysisMode() {
140+
return analysisMode;
141+
}
142+
};
109143
}
110144

145+
Analyzer buildSynonymAnalyzer(TokenizerFactory tokenizer, List<CharFilterFactory> charFilters,
146+
List<TokenFilterFactory> tokenFilters, Function<String, TokenFilterFactory> allFilters) {
147+
return new CustomAnalyzer("dynamic_synonym", tokenizer, charFilters.toArray(new CharFilterFactory[0]),
148+
tokenFilters.stream()
149+
.map(TokenFilterFactory::getSynonymFilter)
150+
.toArray(TokenFilterFactory[]::new));
151+
}
111152

112-
@Override
113-
public TokenStream create(TokenStream tokenStream) {
114-
// fst is null means no synonyms
115-
if (synonymMap == null || synonymMap.fst == null) {
116-
return tokenStream;
153+
SynonymMap buildSynonyms(Analyzer analyzer) {
154+
try {
155+
return getSynonymFile(analyzer).reloadSynonymMap();
156+
} catch (Exception e) {
157+
throw new IllegalArgumentException("failed to build synonyms", e);
117158
}
159+
}
118160

119-
DynamicSynonymFilter dynamicSynonymFilter = new DynamicSynonymFilter(tokenStream, synonymMap, ignoreCase);
120-
dynamicSynonymFilters.put(dynamicSynonymFilter, 1);
121-
122-
return dynamicSynonymFilter;
161+
SynonymFile getSynonymFile(Analyzer analyzer) {
162+
try {
163+
SynonymFile synonymFile;
164+
if (location.startsWith("http://") || location.startsWith("https://")) {
165+
synonymFile = new RemoteSynonymFile(environment, analyzer, expand, format,
166+
location);
167+
} else {
168+
synonymFile = new LocalSynonymFile(environment, analyzer, expand, format,
169+
location);
170+
}
171+
if (scheduledFuture == null) {
172+
scheduledFuture = pool.scheduleAtFixedRate(new Monitor(synonymFile),
173+
interval, interval, TimeUnit.SECONDS);
174+
}
175+
return synonymFile;
176+
} catch (Exception e) {
177+
throw new IllegalArgumentException("failed to get synonyms : " + location, e);
178+
}
123179
}
124180

125181
public class Monitor implements Runnable {

src/main/java/com/bellszhu/elasticsearch/plugin/synonym/service/DynamicSynonymAnalysisService.java

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)