Remove unsafe index options api (#1787)

The IndexOptions api has several problems:
- It is possible to open the same index with different options, which could lead to scoring problems
- If the index is already opened from another task, the options are ignored and the one from the opening task are used
- The analyzer which is derived from the options is used for every field which has not configured a specific analyzer
- This change removes the options api completely.

Co-authored-by: Konstantin Schaper <konstantin.schaper@cloudogu.com>
This commit is contained in:
Sebastian Sdorra
2021-08-31 14:03:16 +02:00
committed by GitHub
parent 61c2ebe80e
commit 765a39e4ce
15 changed files with 23 additions and 229 deletions

View File

@@ -25,45 +25,16 @@
package sonia.scm.search;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.de.GermanAnalyzer;
import org.apache.lucene.analysis.en.EnglishAnalyzer;
import org.apache.lucene.analysis.es.SpanishAnalyzer;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
public class AnalyzerFactory {
@Nonnull
public Analyzer create(IndexOptions options) {
if (options.getType() == IndexOptions.Type.NATURAL_LANGUAGE) {
return createNaturalLanguageAnalyzer(options.getLocale().getLanguage());
}
return createDefaultAnalyzer();
}
private Analyzer createDefaultAnalyzer() {
return new StandardAnalyzer();
}
private Analyzer createNaturalLanguageAnalyzer(String lang) {
switch (lang) {
case "en":
return new EnglishAnalyzer();
case "de":
return new GermanAnalyzer();
case "es":
return new SpanishAnalyzer();
default:
return createDefaultAnalyzer();
}
}
public Analyzer create(LuceneSearchableType type, IndexOptions options) {
Analyzer defaultAnalyzer = create(options);
public Analyzer create(LuceneSearchableType type) {
Analyzer defaultAnalyzer = createDefaultAnalyzer();
Map<String, Analyzer> analyzerMap = new HashMap<>();
for (LuceneSearchableField field : type.getAllFields()) {
@@ -73,6 +44,10 @@ public class AnalyzerFactory {
return new PerFieldAnalyzerWrapper(defaultAnalyzer, analyzerMap);
}
private Analyzer createDefaultAnalyzer() {
return new StandardAnalyzer();
}
private void addFieldAnalyzer(Map<String, Analyzer> analyzerMap, LuceneSearchableField field) {
if (field.getAnalyzer() != Indexed.Analyzer.DEFAULT) {
analyzerMap.put(field.getName(), new NonNaturalLanguageAnalyzer());

View File

@@ -87,7 +87,7 @@ public class IndexManager {
}
public IndexWriter openForWrite(IndexParams indexParams) {
IndexWriterConfig config = new IndexWriterConfig(analyzerFactory.create(indexParams.getSearchableType(), indexParams.getOptions()));
IndexWriterConfig config = new IndexWriterConfig(analyzerFactory.create(indexParams.getSearchableType()));
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
Path path = resolveIndexDirectory(indexParams);

View File

@@ -31,7 +31,6 @@ public class IndexParams implements IndexDetails {
String index;
LuceneSearchableType searchableType;
IndexOptions options;
@Override
public Class<?> getType() {
@@ -47,4 +46,5 @@ public class IndexParams implements IndexDetails {
public String toString() {
return searchableType.getName() + "/" + index;
}
}

View File

@@ -33,7 +33,6 @@ public abstract class LuceneIndexTask implements Runnable, Serializable {
private final Class<?> type;
private final String indexName;
private final IndexOptions options;
private transient LuceneIndexFactory indexFactory;
private transient SearchableTypeResolver searchableTypeResolver;
@@ -42,7 +41,6 @@ public abstract class LuceneIndexTask implements Runnable, Serializable {
protected LuceneIndexTask(IndexParams params) {
this.type = params.getSearchableType().getType();
this.indexName = params.getIndex();
this.options = params.getOptions();
}
@Inject
@@ -66,7 +64,7 @@ public abstract class LuceneIndexTask implements Runnable, Serializable {
public void run() {
LuceneSearchableType searchableType = searchableTypeResolver.resolve(type);
IndexTask<?> task = task(injector);
try (LuceneIndex index = indexFactory.create(new IndexParams(indexName, searchableType, options))) {
try (LuceneIndex index = indexFactory.create(new IndexParams(indexName, searchableType))) {
task.update(index);
}
task.afterUpdate();

View File

@@ -42,7 +42,7 @@ public class LuceneQueryBuilderFactory {
indexManager,
indexParams.getIndex(),
indexParams.getSearchableType(),
analyzerFactory.create(indexParams.getSearchableType(), indexParams.getOptions())
analyzerFactory.create(indexParams.getSearchableType())
);
}

View File

@@ -101,7 +101,6 @@ public class LuceneSearchEngine implements SearchEngine {
private final List<String> resources = new ArrayList<>();
private Predicate<IndexDetails> predicate = details -> true;
private IndexOptions options = IndexOptions.defaults();
@Override
public ForIndices matching(Predicate<IndexDetails> predicate) {
@@ -109,12 +108,6 @@ public class LuceneSearchEngine implements SearchEngine {
return this;
}
@Override
public ForIndices withOptions(IndexOptions options) {
this.options = options;
return this;
}
@Override
public ForIndices forResource(String resource) {
this.resources.add(resource);
@@ -135,7 +128,7 @@ public class LuceneSearchEngine implements SearchEngine {
indexManager.all()
.stream()
.filter(predicate)
.map(details -> new IndexParams(details.getName(), resolver.resolve(details.getType()), options))
.map(details -> new IndexParams(details.getName(), resolver.resolve(details.getType())))
.forEach(consumer);
}
@@ -147,7 +140,6 @@ public class LuceneSearchEngine implements SearchEngine {
class LuceneForType<T> implements ForType<T> {
private final LuceneSearchableType searchableType;
private IndexOptions options = IndexOptions.defaults();
private String index = "default";
private final List<String> resources = new ArrayList<>();
@@ -155,12 +147,6 @@ public class LuceneSearchEngine implements SearchEngine {
this.searchableType = searchableType;
}
@Override
public ForType<T> withOptions(IndexOptions options) {
this.options = options;
return this;
}
@Override
public ForType<T> withIndex(String index) {
this.index = index;
@@ -168,7 +154,7 @@ public class LuceneSearchEngine implements SearchEngine {
}
private IndexParams params() {
return new IndexParams(index, searchableType, options);
return new IndexParams(index, searchableType);
}
@Override