diff --git a/src/main/java/org/codelibs/fess/helper/SystemHelper.java b/src/main/java/org/codelibs/fess/helper/SystemHelper.java index 532af0f61..70026fc36 100644 --- a/src/main/java/org/codelibs/fess/helper/SystemHelper.java +++ b/src/main/java/org/codelibs/fess/helper/SystemHelper.java @@ -517,6 +517,8 @@ public class SystemHelper { ComponentUtil.getJobManager().reboot(); } updateSystemProperties(); + + ComponentUtil.getRankFusionProcessor().update(); } public void updateSystemProperties() { diff --git a/src/main/java/org/codelibs/fess/rank/fusion/RankFusionProcessor.java b/src/main/java/org/codelibs/fess/rank/fusion/RankFusionProcessor.java index 3b745baec..32be2e30f 100644 --- a/src/main/java/org/codelibs/fess/rank/fusion/RankFusionProcessor.java +++ b/src/main/java/org/codelibs/fess/rank/fusion/RankFusionProcessor.java @@ -17,6 +17,7 @@ package org.codelibs.fess.rank.fusion; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -28,11 +29,15 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.search.TotalHits.Relation; import org.codelibs.core.collection.ArrayUtil; +import org.codelibs.core.concurrent.CommonPoolUtil; +import org.codelibs.core.lang.StringUtil; +import org.codelibs.core.stream.StreamUtil; import org.codelibs.fess.Constants; import org.codelibs.fess.entity.FacetInfo; import org.codelibs.fess.entity.GeoInfo; @@ -65,6 +70,8 @@ public class RankFusionProcessor implements AutoCloseable { protected int windowSize; + protected Set availableSearcherNameSet; + @PostConstruct public void init() { final FessConfig fessConfig = ComponentUtil.getFessConfig(); @@ -77,6 +84,24 @@ public class RankFusionProcessor implements AutoCloseable { } else { this.windowSize = windowSize; } + load(); + } + + public void update() { + CommonPoolUtil.execute(this::load); + } + + protected void load() { + final String value = System.getProperty("rank.fusion.searchers"); + if (StringUtil.isBlank(value)) { + availableSearcherNameSet = Collections.emptySet(); + } else { + availableSearcherNameSet = StreamUtil.split(value, ",") + .get(stream -> stream.map(String::trim).filter(StringUtil::isNotBlank).collect(Collectors.toUnmodifiableSet())); + } + if (logger.isDebugEnabled()) { + logger.debug("availableSearcherNameSet={}", availableSearcherNameSet); + } } @Override @@ -98,14 +123,30 @@ public class RankFusionProcessor implements AutoCloseable { public List> search(final String query, final SearchRequestParams params, final OptionalThing userBean) { - if (searchers.length == 1) { - return searchWithMainSearcher(query, params, userBean); + final RankFusionSearcher[] availableSearchers = getAvailableSearchers(); + if (availableSearchers.length == 1) { + return searchWithMainSearcher(availableSearchers[0], query, params, userBean); } - return searchWithMultipleSearchers(query, params, userBean); + return searchWithMultipleSearchers(availableSearchers, query, params, userBean); } - protected List> searchWithMultipleSearchers(final String query, final SearchRequestParams params, - final OptionalThing userBean) { + protected RankFusionSearcher[] getAvailableSearchers() { + if (availableSearcherNameSet.isEmpty()) { + return searchers; + } + final RankFusionSearcher[] availableSearchers = Arrays.stream(searchers) + .filter(searcher -> availableSearcherNameSet.contains(searcher.getName())).toArray(n -> new RankFusionSearcher[n]); + if (availableSearchers.length == 0) { + if (logger.isDebugEnabled()) { + logger.debug("No available searchers from {}", availableSearcherNameSet); + } + return new RankFusionSearcher[] { searchers[0] }; + } + return availableSearchers; + } + + protected List> searchWithMultipleSearchers(final RankFusionSearcher[] searchers, final String query, + final SearchRequestParams params, final OptionalThing userBean) { if (logger.isDebugEnabled()) { logger.debug("Send {} to the searchers.", query); } @@ -192,13 +233,13 @@ public class RankFusionProcessor implements AutoCloseable { final Map baseDoc = scoreDocMap.get(id); final float oldScore = toFloat(baseDoc.get(scoreField)); baseDoc.put(scoreField, oldScore + score); - final String[] searchers = DocumentUtil.getValue(doc, Constants.SEARCHER, String[].class); - if (searchers != null) { + final String[] searcherNames = DocumentUtil.getValue(doc, Constants.SEARCHER, String[].class); + if (searcherNames != null) { final String[] baseSearchers = DocumentUtil.getValue(baseDoc, Constants.SEARCHER, String[].class); if (baseSearchers != null) { - baseDoc.put(Constants.SEARCHER, ArrayUtil.addAll(baseSearchers, searchers)); + baseDoc.put(Constants.SEARCHER, ArrayUtil.addAll(baseSearchers, searcherNames)); } else { - baseDoc.put(Constants.SEARCHER, searchers); + baseDoc.put(Constants.SEARCHER, searcherNames); } } } else { @@ -248,13 +289,13 @@ public class RankFusionProcessor implements AutoCloseable { return docs.subList(fromIndex, toIndex); } - protected List> searchWithMainSearcher(final String query, final SearchRequestParams params, - final OptionalThing userBean) { + protected List> searchWithMainSearcher(final RankFusionSearcher searcher, final String query, + final SearchRequestParams params, final OptionalThing userBean) { if (logger.isDebugEnabled()) { logger.debug("Send {} to the main searcher.", query); } final int pageSize = params.getPageSize(); - final SearchResult searchResult = searchers[0].search(query, params, userBean); + final SearchResult searchResult = searcher.search(query, params, userBean); return createResponseList(searchResult.getDocumentList(), searchResult.getAllRecordCount(), searchResult.getAllRecordCountRelation(), searchResult.getQueryTime(), searchResult.isPartialResults(), searchResult.getFacetResponse(), params.getStartPosition(), pageSize, 0);