This commit is contained in:
parent
dc62cd476c
commit
51b715f2bc
|
@ -0,0 +1,6 @@
|
||||||
|
pr: 125659
|
||||||
|
summary: Non existing synonyms sets do not fail shard recovery for indices
|
||||||
|
area: "Analysis"
|
||||||
|
type: bug
|
||||||
|
issues:
|
||||||
|
- 125603
|
|
@ -74,7 +74,7 @@ public class SynonymTokenFilterFactory extends AbstractTokenFilterFactory {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
reader = new ReaderWithOrigin(
|
reader = new ReaderWithOrigin(
|
||||||
Analysis.getReaderFromIndex(synonymsSet, factory.synonymsManagementAPIService),
|
Analysis.getReaderFromIndex(synonymsSet, factory.synonymsManagementAPIService, factory.lenient),
|
||||||
"[" + synonymsSet + "] synonyms_set in .synonyms index",
|
"[" + synonymsSet + "] synonyms_set in .synonyms index",
|
||||||
synonymsSet
|
synonymsSet
|
||||||
);
|
);
|
||||||
|
|
|
@ -64,9 +64,6 @@ excludeList.add('cluster.desired_nodes/20_dry_run/Test validation works for dry
|
||||||
// Excluded because they create dot-prefixed indices on older versions
|
// Excluded because they create dot-prefixed indices on older versions
|
||||||
excludeList.add('indices.resolve_index/20_resolve_system_index/*')
|
excludeList.add('indices.resolve_index/20_resolve_system_index/*')
|
||||||
|
|
||||||
// Can't work until auto-expand replicas is 0-1 for synonyms index
|
|
||||||
excludeList.add("synonyms/90_synonyms_reloading_for_synset/Reload analyzers for specific synonym set")
|
|
||||||
|
|
||||||
def clusterPath = getPath()
|
def clusterPath = getPath()
|
||||||
|
|
||||||
buildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
|
buildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
|
||||||
|
|
|
@ -278,4 +278,5 @@ tasks.named("yamlRestTestV7CompatTransform").configure({ task ->
|
||||||
task.skipTest("search.vectors/160_knn_query_missing_params/kNN search in a dis_max query - missing num_candidates", "waiting for #118774 backport")
|
task.skipTest("search.vectors/160_knn_query_missing_params/kNN search in a dis_max query - missing num_candidates", "waiting for #118774 backport")
|
||||||
task.skipTest("migration/10_get_feature_upgrade_status/Get feature upgrade status", "Moved to plugin")
|
task.skipTest("migration/10_get_feature_upgrade_status/Get feature upgrade status", "Moved to plugin")
|
||||||
task.skipTest("migration/20_post_feature_upgrade/Get feature upgrade status", "Moved to plugin")
|
task.skipTest("migration/20_post_feature_upgrade/Get feature upgrade status", "Moved to plugin")
|
||||||
|
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")
|
||||||
})
|
})
|
||||||
|
|
|
@ -315,3 +315,160 @@ setup:
|
||||||
indices.stats: { index: test_index }
|
indices.stats: { index: test_index }
|
||||||
|
|
||||||
- length: { indices: 0 }
|
- length: { indices: 0 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Load index with non existent synonyms set":
|
||||||
|
- requires:
|
||||||
|
cluster_features: [ index.synonyms_set_lenient_on_non_existing ]
|
||||||
|
reason: "requires synonyms_set_lenient_on_non_existing bug fix"
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: test_index
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
index:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
analysis:
|
||||||
|
filter:
|
||||||
|
my_synonym_filter:
|
||||||
|
type: synonym
|
||||||
|
synonyms_set: set1
|
||||||
|
updateable: true
|
||||||
|
analyzer:
|
||||||
|
my_analyzer:
|
||||||
|
type: custom
|
||||||
|
tokenizer: whitespace
|
||||||
|
filter: [ lowercase, my_synonym_filter ]
|
||||||
|
mappings:
|
||||||
|
properties:
|
||||||
|
my_field:
|
||||||
|
type: text
|
||||||
|
search_analyzer: my_analyzer
|
||||||
|
|
||||||
|
- match: { acknowledged: true }
|
||||||
|
- match: { shards_acknowledged: true }
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.stats: { index: test_index }
|
||||||
|
|
||||||
|
- match: { indices.test_index.health: "green" }
|
||||||
|
|
||||||
|
# Synonyms are not applied
|
||||||
|
- do:
|
||||||
|
indices.analyze:
|
||||||
|
index: test_index
|
||||||
|
body:
|
||||||
|
analyzer: my_analyzer
|
||||||
|
text: foo
|
||||||
|
|
||||||
|
- length: { tokens: 1 }
|
||||||
|
- match: { tokens.0.token: foo }
|
||||||
|
|
||||||
|
|
||||||
|
# Create synonyms set and check synonyms are applied
|
||||||
|
- do:
|
||||||
|
synonyms.put_synonym:
|
||||||
|
id: set1
|
||||||
|
body:
|
||||||
|
synonyms_set:
|
||||||
|
synonyms: "foo => bar, baz"
|
||||||
|
|
||||||
|
# This is to ensure that all index shards (write and read) are available. In serverless this can take some time.
|
||||||
|
- do:
|
||||||
|
cluster.health:
|
||||||
|
index: .synonyms
|
||||||
|
wait_for_status: green
|
||||||
|
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.stats: { index: test_index }
|
||||||
|
|
||||||
|
- match: { indices.test_index.health: "green" }
|
||||||
|
|
||||||
|
# Synonyms are applied
|
||||||
|
- do:
|
||||||
|
indices.analyze:
|
||||||
|
index: test_index
|
||||||
|
body:
|
||||||
|
analyzer: my_analyzer
|
||||||
|
text: foo
|
||||||
|
|
||||||
|
- length: { tokens: 2 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Load index with non existent synonyms set and lenient set to false":
|
||||||
|
- requires:
|
||||||
|
test_runner_features: [ allowed_warnings ]
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: test_index
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
index:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 0
|
||||||
|
analysis:
|
||||||
|
filter:
|
||||||
|
my_synonym_filter:
|
||||||
|
type: synonym
|
||||||
|
synonyms_set: set1
|
||||||
|
updateable: true
|
||||||
|
lenient: false
|
||||||
|
analyzer:
|
||||||
|
my_analyzer:
|
||||||
|
type: custom
|
||||||
|
tokenizer: whitespace
|
||||||
|
filter: [ lowercase, my_synonym_filter ]
|
||||||
|
mappings:
|
||||||
|
properties:
|
||||||
|
my_field:
|
||||||
|
type: text
|
||||||
|
search_analyzer: my_analyzer
|
||||||
|
|
||||||
|
- match: { acknowledged: true }
|
||||||
|
- match: { shards_acknowledged: false }
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.stats: { index: test_index }
|
||||||
|
|
||||||
|
- length: { indices: 0 }
|
||||||
|
|
||||||
|
# Create synonyms set and check synonyms are applied
|
||||||
|
- do:
|
||||||
|
synonyms.put_synonym:
|
||||||
|
id: set1
|
||||||
|
body:
|
||||||
|
synonyms_set:
|
||||||
|
synonyms: "foo => bar, baz"
|
||||||
|
|
||||||
|
# This is to ensure that all index shards (write and read) are available. In serverless this can take some time.
|
||||||
|
- do:
|
||||||
|
cluster.health:
|
||||||
|
index: .synonyms
|
||||||
|
# BWC tests won't be able to get green - synonyms index is 0-all, so some shards won't be recovered in older nodes
|
||||||
|
wait_for_status: yellow
|
||||||
|
|
||||||
|
- do:
|
||||||
|
# Warning issued in previous versions
|
||||||
|
allowed_warnings:
|
||||||
|
- "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."
|
||||||
|
cluster.reroute:
|
||||||
|
retry_failed: true
|
||||||
|
|
||||||
|
- do:
|
||||||
|
cluster.health:
|
||||||
|
index: test_index
|
||||||
|
wait_for_status: green
|
||||||
|
|
||||||
|
# Synonyms are applied
|
||||||
|
- do:
|
||||||
|
indices.analyze:
|
||||||
|
index: test_index
|
||||||
|
body:
|
||||||
|
analyzer: my_analyzer
|
||||||
|
text: foo
|
||||||
|
|
||||||
|
- length: { tokens: 2 }
|
||||||
|
|
||||||
|
|
|
@ -168,34 +168,6 @@ setup:
|
||||||
query: hola
|
query: hola
|
||||||
- match: { hits.total.value: 1 }
|
- match: { hits.total.value: 1 }
|
||||||
|
|
||||||
---
|
|
||||||
"Fail loading synonyms from index if synonyms_set doesn't exist":
|
|
||||||
- do:
|
|
||||||
indices.create:
|
|
||||||
index: another_index
|
|
||||||
body:
|
|
||||||
settings:
|
|
||||||
index:
|
|
||||||
number_of_shards: 1
|
|
||||||
analysis:
|
|
||||||
filter:
|
|
||||||
my_synonym_filter:
|
|
||||||
type: synonym
|
|
||||||
synonyms_set: set_missing
|
|
||||||
updateable: true
|
|
||||||
analyzer:
|
|
||||||
my_analyzer:
|
|
||||||
type: custom
|
|
||||||
tokenizer: standard
|
|
||||||
filter: [ lowercase, my_synonym_filter ]
|
|
||||||
mappings:
|
|
||||||
properties:
|
|
||||||
my_field:
|
|
||||||
type: text
|
|
||||||
search_analyzer: my_analyzer
|
|
||||||
- match: { acknowledged: true }
|
|
||||||
- match: { shards_acknowledged: false }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
"Load empty synonyms set from index for an analyzer":
|
"Load empty synonyms set from index for an analyzer":
|
||||||
- do:
|
- do:
|
||||||
|
|
|
@ -23,8 +23,10 @@ public class IndexFeatures implements FeatureSpecification {
|
||||||
|
|
||||||
public static final NodeFeature LOGSDB_NO_HOST_NAME_FIELD = new NodeFeature("index.logsdb_no_host_name_field");
|
public static final NodeFeature LOGSDB_NO_HOST_NAME_FIELD = new NodeFeature("index.logsdb_no_host_name_field");
|
||||||
|
|
||||||
|
private static final NodeFeature SYNONYMS_SET_LENIENT_ON_NON_EXISTING = new NodeFeature("index.synonyms_set_lenient_on_non_existing");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<NodeFeature> getTestFeatures() {
|
public Set<NodeFeature> getTestFeatures() {
|
||||||
return Set.of(LOGSDB_NO_HOST_NAME_FIELD);
|
return Set.of(LOGSDB_NO_HOST_NAME_FIELD, SYNONYMS_SET_LENIENT_ON_NON_EXISTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.lucene.analysis.sv.SwedishAnalyzer;
|
||||||
import org.apache.lucene.analysis.th.ThaiAnalyzer;
|
import org.apache.lucene.analysis.th.ThaiAnalyzer;
|
||||||
import org.apache.lucene.analysis.tr.TurkishAnalyzer;
|
import org.apache.lucene.analysis.tr.TurkishAnalyzer;
|
||||||
import org.apache.lucene.analysis.util.CSVUtil;
|
import org.apache.lucene.analysis.util.CSVUtil;
|
||||||
|
import org.elasticsearch.ResourceNotFoundException;
|
||||||
import org.elasticsearch.action.support.PlainActionFuture;
|
import org.elasticsearch.action.support.PlainActionFuture;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.logging.DeprecationCategory;
|
import org.elasticsearch.common.logging.DeprecationCategory;
|
||||||
|
@ -367,10 +368,39 @@ public class Analysis {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Reader getReaderFromIndex(String synonymsSet, SynonymsManagementAPIService synonymsManagementAPIService) {
|
public static Reader getReaderFromIndex(
|
||||||
|
String synonymsSet,
|
||||||
|
SynonymsManagementAPIService synonymsManagementAPIService,
|
||||||
|
boolean ignoreMissing
|
||||||
|
) {
|
||||||
final PlainActionFuture<PagedResult<SynonymRule>> synonymsLoadingFuture = new PlainActionFuture<>();
|
final PlainActionFuture<PagedResult<SynonymRule>> synonymsLoadingFuture = new PlainActionFuture<>();
|
||||||
synonymsManagementAPIService.getSynonymSetRules(synonymsSet, synonymsLoadingFuture);
|
synonymsManagementAPIService.getSynonymSetRules(synonymsSet, synonymsLoadingFuture);
|
||||||
PagedResult<SynonymRule> results = synonymsLoadingFuture.actionGet();
|
|
||||||
|
PagedResult<SynonymRule> results;
|
||||||
|
|
||||||
|
try {
|
||||||
|
results = synonymsLoadingFuture.actionGet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (ignoreMissing == false) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean notFound = e instanceof ResourceNotFoundException;
|
||||||
|
String message = String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Synonyms set %s %s. Synonyms will not be applied to search results on indices that use this synonym set",
|
||||||
|
synonymsSet,
|
||||||
|
notFound ? "not found" : "could not be loaded"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (notFound) {
|
||||||
|
logger.warn(message);
|
||||||
|
} else {
|
||||||
|
logger.error(message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
results = new PagedResult<>(0, new SynonymRule[0]);
|
||||||
|
}
|
||||||
|
|
||||||
SynonymRule[] synonymRules = results.pageResults();
|
SynonymRule[] synonymRules = results.pageResults();
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
Loading…
Reference in New Issue