Skip to content

Commit 51b715f

Browse files
authored
[8.18] Non existing synonyms sets do not fail shard recovery (elastic#125659) (elastic#125796)
1 parent dc62cd4 commit 51b715f

File tree

8 files changed

+200
-35
lines changed

8 files changed

+200
-35
lines changed

docs/changelog/125659.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 125659
2+
summary: Non existing synonyms sets do not fail shard recovery for indices
3+
area: "Analysis"
4+
type: bug
5+
issues:
6+
- 125603

modules/analysis-common/src/main/java/org/elasticsearch/analysis/common/SynonymTokenFilterFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public ReaderWithOrigin getRulesReader(SynonymTokenFilterFactory factory, IndexC
7474
);
7575
} else {
7676
reader = new ReaderWithOrigin(
77-
Analysis.getReaderFromIndex(synonymsSet, factory.synonymsManagementAPIService),
77+
Analysis.getReaderFromIndex(synonymsSet, factory.synonymsManagementAPIService, factory.lenient),
7878
"[" + synonymsSet + "] synonyms_set in .synonyms index",
7979
synonymsSet
8080
);

qa/mixed-cluster/build.gradle

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@ excludeList.add('cluster.desired_nodes/20_dry_run/Test validation works for dry
6464
// Excluded because they create dot-prefixed indices on older versions
6565
excludeList.add('indices.resolve_index/20_resolve_system_index/*')
6666

67-
// Can't work until auto-expand replicas is 0-1 for synonyms index
68-
excludeList.add("synonyms/90_synonyms_reloading_for_synset/Reload analyzers for specific synonym set")
69-
7067
def clusterPath = getPath()
7168

7269
buildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->

rest-api-spec/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,5 @@ tasks.named("yamlRestTestV7CompatTransform").configure({ task ->
278278
task.skipTest("search.vectors/160_knn_query_missing_params/kNN search in a dis_max query - missing num_candidates", "waiting for #118774 backport")
279279
task.skipTest("migration/10_get_feature_upgrade_status/Get feature upgrade status", "Moved to plugin")
280280
task.skipTest("migration/20_post_feature_upgrade/Get feature upgrade status", "Moved to plugin")
281+
task.skipTest("synonyms/80_synonyms_from_index/Fail loading synonyms from index if synonyms_set doesn't exist", "Synonyms do no longer fail if the synonyms_set doesn't exist")
281282
})

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/synonyms/110_synonyms_invalid.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,160 @@ setup:
315315
indices.stats: { index: test_index }
316316

317317
- length: { indices: 0 }
318+
319+
---
320+
"Load index with non existent synonyms set":
321+
- requires:
322+
cluster_features: [ index.synonyms_set_lenient_on_non_existing ]
323+
reason: "requires synonyms_set_lenient_on_non_existing bug fix"
324+
- do:
325+
indices.create:
326+
index: test_index
327+
body:
328+
settings:
329+
index:
330+
number_of_shards: 1
331+
number_of_replicas: 0
332+
analysis:
333+
filter:
334+
my_synonym_filter:
335+
type: synonym
336+
synonyms_set: set1
337+
updateable: true
338+
analyzer:
339+
my_analyzer:
340+
type: custom
341+
tokenizer: whitespace
342+
filter: [ lowercase, my_synonym_filter ]
343+
mappings:
344+
properties:
345+
my_field:
346+
type: text
347+
search_analyzer: my_analyzer
348+
349+
- match: { acknowledged: true }
350+
- match: { shards_acknowledged: true }
351+
352+
- do:
353+
indices.stats: { index: test_index }
354+
355+
- match: { indices.test_index.health: "green" }
356+
357+
# Synonyms are not applied
358+
- do:
359+
indices.analyze:
360+
index: test_index
361+
body:
362+
analyzer: my_analyzer
363+
text: foo
364+
365+
- length: { tokens: 1 }
366+
- match: { tokens.0.token: foo }
367+
368+
369+
# Create synonyms set and check synonyms are applied
370+
- do:
371+
synonyms.put_synonym:
372+
id: set1
373+
body:
374+
synonyms_set:
375+
synonyms: "foo => bar, baz"
376+
377+
# This is to ensure that all index shards (write and read) are available. In serverless this can take some time.
378+
- do:
379+
cluster.health:
380+
index: .synonyms
381+
wait_for_status: green
382+
383+
384+
- do:
385+
indices.stats: { index: test_index }
386+
387+
- match: { indices.test_index.health: "green" }
388+
389+
# Synonyms are applied
390+
- do:
391+
indices.analyze:
392+
index: test_index
393+
body:
394+
analyzer: my_analyzer
395+
text: foo
396+
397+
- length: { tokens: 2 }
398+
399+
---
400+
"Load index with non existent synonyms set and lenient set to false":
401+
- requires:
402+
test_runner_features: [ allowed_warnings ]
403+
404+
- do:
405+
indices.create:
406+
index: test_index
407+
body:
408+
settings:
409+
index:
410+
number_of_shards: 1
411+
number_of_replicas: 0
412+
analysis:
413+
filter:
414+
my_synonym_filter:
415+
type: synonym
416+
synonyms_set: set1
417+
updateable: true
418+
lenient: false
419+
analyzer:
420+
my_analyzer:
421+
type: custom
422+
tokenizer: whitespace
423+
filter: [ lowercase, my_synonym_filter ]
424+
mappings:
425+
properties:
426+
my_field:
427+
type: text
428+
search_analyzer: my_analyzer
429+
430+
- match: { acknowledged: true }
431+
- match: { shards_acknowledged: false }
432+
433+
- do:
434+
indices.stats: { index: test_index }
435+
436+
- length: { indices: 0 }
437+
438+
# Create synonyms set and check synonyms are applied
439+
- do:
440+
synonyms.put_synonym:
441+
id: set1
442+
body:
443+
synonyms_set:
444+
synonyms: "foo => bar, baz"
445+
446+
# This is to ensure that all index shards (write and read) are available. In serverless this can take some time.
447+
- do:
448+
cluster.health:
449+
index: .synonyms
450+
# BWC tests won't be able to get green - synonyms index is 0-all, so some shards won't be recovered in older nodes
451+
wait_for_status: yellow
452+
453+
- do:
454+
# Warning issued in previous versions
455+
allowed_warnings:
456+
- "The [state] field in the response to the reroute API is deprecated and will be removed in a future version. Specify ?metric=none to adopt the future behaviour."
457+
cluster.reroute:
458+
retry_failed: true
459+
460+
- do:
461+
cluster.health:
462+
index: test_index
463+
wait_for_status: green
464+
465+
# Synonyms are applied
466+
- do:
467+
indices.analyze:
468+
index: test_index
469+
body:
470+
analyzer: my_analyzer
471+
text: foo
472+
473+
- length: { tokens: 2 }
474+

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/synonyms/80_synonyms_from_index.yml

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -168,34 +168,6 @@ setup:
168168
query: hola
169169
- match: { hits.total.value: 1 }
170170

171-
---
172-
"Fail loading synonyms from index if synonyms_set doesn't exist":
173-
- do:
174-
indices.create:
175-
index: another_index
176-
body:
177-
settings:
178-
index:
179-
number_of_shards: 1
180-
analysis:
181-
filter:
182-
my_synonym_filter:
183-
type: synonym
184-
synonyms_set: set_missing
185-
updateable: true
186-
analyzer:
187-
my_analyzer:
188-
type: custom
189-
tokenizer: standard
190-
filter: [ lowercase, my_synonym_filter ]
191-
mappings:
192-
properties:
193-
my_field:
194-
type: text
195-
search_analyzer: my_analyzer
196-
- match: { acknowledged: true }
197-
- match: { shards_acknowledged: false }
198-
199171
---
200172
"Load empty synonyms set from index for an analyzer":
201173
- do:

server/src/main/java/org/elasticsearch/index/IndexFeatures.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ public Set<NodeFeature> getFeatures() {
2323

2424
public static final NodeFeature LOGSDB_NO_HOST_NAME_FIELD = new NodeFeature("index.logsdb_no_host_name_field");
2525

26+
private static final NodeFeature SYNONYMS_SET_LENIENT_ON_NON_EXISTING = new NodeFeature("index.synonyms_set_lenient_on_non_existing");
27+
2628
@Override
2729
public Set<NodeFeature> getTestFeatures() {
28-
return Set.of(LOGSDB_NO_HOST_NAME_FIELD);
30+
return Set.of(LOGSDB_NO_HOST_NAME_FIELD, SYNONYMS_SET_LENIENT_ON_NON_EXISTING);
2931
}
3032
}

server/src/main/java/org/elasticsearch/index/analysis/Analysis.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.apache.lucene.analysis.th.ThaiAnalyzer;
4949
import org.apache.lucene.analysis.tr.TurkishAnalyzer;
5050
import org.apache.lucene.analysis.util.CSVUtil;
51+
import org.elasticsearch.ResourceNotFoundException;
5152
import org.elasticsearch.action.support.PlainActionFuture;
5253
import org.elasticsearch.common.Strings;
5354
import org.elasticsearch.common.logging.DeprecationCategory;
@@ -367,10 +368,39 @@ public static Reader getReaderFromFile(Environment env, String filePath, String
367368
}
368369
}
369370

370-
public static Reader getReaderFromIndex(String synonymsSet, SynonymsManagementAPIService synonymsManagementAPIService) {
371+
public static Reader getReaderFromIndex(
372+
String synonymsSet,
373+
SynonymsManagementAPIService synonymsManagementAPIService,
374+
boolean ignoreMissing
375+
) {
371376
final PlainActionFuture<PagedResult<SynonymRule>> synonymsLoadingFuture = new PlainActionFuture<>();
372377
synonymsManagementAPIService.getSynonymSetRules(synonymsSet, synonymsLoadingFuture);
373-
PagedResult<SynonymRule> results = synonymsLoadingFuture.actionGet();
378+
379+
PagedResult<SynonymRule> results;
380+
381+
try {
382+
results = synonymsLoadingFuture.actionGet();
383+
} catch (Exception e) {
384+
if (ignoreMissing == false) {
385+
throw e;
386+
}
387+
388+
boolean notFound = e instanceof ResourceNotFoundException;
389+
String message = String.format(
390+
Locale.ROOT,
391+
"Synonyms set %s %s. Synonyms will not be applied to search results on indices that use this synonym set",
392+
synonymsSet,
393+
notFound ? "not found" : "could not be loaded"
394+
);
395+
396+
if (notFound) {
397+
logger.warn(message);
398+
} else {
399+
logger.error(message, e);
400+
}
401+
402+
results = new PagedResult<>(0, new SynonymRule[0]);
403+
}
374404

375405
SynonymRule[] synonymRules = results.pageResults();
376406
StringBuilder sb = new StringBuilder();

0 commit comments

Comments
 (0)