diff --git a/src/main/java/org/codelibs/fess/entity/HighlightInfo.java b/src/main/java/org/codelibs/fess/entity/HighlightInfo.java index 1e1449368..c52208560 100644 --- a/src/main/java/org/codelibs/fess/entity/HighlightInfo.java +++ b/src/main/java/org/codelibs/fess/entity/HighlightInfo.java @@ -22,12 +22,14 @@ public class HighlightInfo { private String type; private int fragmentSize; private int numOfFragments; + private int fragmentOffset; public HighlightInfo() { final FessConfig fessConfig = ComponentUtil.getFessConfig(); this.type = fessConfig.getQueryHighlightType(); this.fragmentSize = fessConfig.getQueryHighlightFragmentSizeAsInteger(); this.numOfFragments = fessConfig.getQueryHighlightNumberOfFragmentsAsInteger(); + this.fragmentOffset = fessConfig.getQueryHighlightFragmentOffsetAsInteger(); } public String getType() { @@ -56,4 +58,13 @@ public class HighlightInfo { this.numOfFragments = numOfFragments; return this; } + + public int getFragmentOffset() { + return fragmentOffset; + } + + public HighlightInfo fragmentOffset(final int fragmentOffset) { + this.fragmentOffset = fragmentOffset; + return this; + } } diff --git a/src/main/java/org/codelibs/fess/es/client/FessEsClient.java b/src/main/java/org/codelibs/fess/es/client/FessEsClient.java index ae8106392..84632f250 100644 --- a/src/main/java/org/codelibs/fess/es/client/FessEsClient.java +++ b/src/main/java/org/codelibs/fess/es/client/FessEsClient.java @@ -1108,8 +1108,116 @@ public class FessEsClient implements Client { throw new ResultOffsetExceededException("The number of result size is exceeded."); } - final QueryContext queryContext = - queryHelper.build(searchRequestType, query, context -> { + final QueryContext queryContext = buildQueryContext(queryHelper, fessConfig); + + searchRequestBuilder.setFrom(offset).setSize(size); + + final Object trackTotalHitsValue = fessConfig.getQueryTrackTotalHitsValue(); + if (trackTotalHitsValue instanceof Boolean) { + searchRequestBuilder.setTrackTotalHits((Boolean) trackTotalHitsValue); + } else if (trackTotalHitsValue instanceof Number) { + searchRequestBuilder.setTrackTotalHitsUpTo(((Number) trackTotalHitsValue).intValue()); + } + + if (responseFields != null) { + searchRequestBuilder.setFetchSource(responseFields, null); + } + + // rescorer + buildRescorer(queryHelper, fessConfig); + + // sort + buildSort(queryContext, fessConfig); + + // highlighting + if (highlightInfo != null) { + buildHighlighter(queryHelper, fessConfig); + } + + // facets + if (facetInfo != null) { + buildFacet(queryHelper, fessConfig); + } + + if (!SearchRequestType.ADMIN_SEARCH.equals(searchRequestType) && !isScroll && fessConfig.isResultCollapsed() + && similarDocHash == null) { + searchRequestBuilder.setCollapse(getCollapseBuilder(fessConfig)); + } + + searchRequestBuilder.setQuery(queryContext.getQueryBuilder()); + return true; + } + + protected void buildFacet(final QueryHelper queryHelper, final FessConfig fessConfig) { + stream(facetInfo.field).of( + stream -> stream.forEach(f -> { + if (queryHelper.isFacetField(f)) { + final String encodedField = BaseEncoding.base64().encode(f.getBytes(StandardCharsets.UTF_8)); + final TermsAggregationBuilder termsBuilder = + AggregationBuilders.terms(Constants.FACET_FIELD_PREFIX + encodedField).field(f); + termsBuilder.order(facetInfo.getBucketOrder()); + if (facetInfo.size != null) { + termsBuilder.size(facetInfo.size); + } + if (facetInfo.minDocCount != null) { + termsBuilder.minDocCount(facetInfo.minDocCount); + } + if (facetInfo.missing != null) { + termsBuilder.missing(facetInfo.missing); + } + searchRequestBuilder.addAggregation(termsBuilder); + } else { + throw new SearchQueryException("Invalid facet field: " + f); + } + })); + stream(facetInfo.query) + .of(stream -> stream.forEach(fq -> { + final QueryContext facetContext = new QueryContext(fq, false); + queryHelper.buildBaseQuery(facetContext, c -> {}); + final String encodedFacetQuery = BaseEncoding.base64().encode(fq.getBytes(StandardCharsets.UTF_8)); + final FilterAggregationBuilder filterBuilder = + AggregationBuilders.filter(Constants.FACET_QUERY_PREFIX + encodedFacetQuery, facetContext.getQueryBuilder()); + searchRequestBuilder.addAggregation(filterBuilder); + })); + } + + protected void buildHighlighter(final QueryHelper queryHelper, final FessConfig fessConfig) { + final String highlighterType = highlightInfo.getType(); + final int fragmentSize = highlightInfo.getFragmentSize(); + final int numOfFragments = highlightInfo.getNumOfFragments(); + final int fragmentOffset = highlightInfo.getFragmentOffset(); + final char[] boundaryChars = fessConfig.getQueryHighlightBoundaryCharsAsArray(); + final int boundaryMaxScan = fessConfig.getQueryHighlightBoundaryMaxScanAsInteger(); + final String boundaryScannerType = fessConfig.getQueryHighlightBoundaryScanner(); + final boolean forceSource = fessConfig.isQueryHighlightForceSource(); + final String fragmenter = fessConfig.getQueryHighlightFragmenter(); + final int noMatchSize = fessConfig.getQueryHighlightNoMatchSizeAsInteger(); + final String order = fessConfig.getQueryHighlightOrder(); + final int phraseLimit = fessConfig.getQueryHighlightPhraseLimitAsInteger(); + final String encoder = fessConfig.getQueryHighlightEncoder(); + final HighlightBuilder highlightBuilder = new HighlightBuilder(); + queryHelper.highlightedFields(stream -> stream.forEach(hf -> highlightBuilder.field( + new HighlightBuilder.Field(hf).highlighterType(highlighterType).fragmentSize(fragmentSize) + .numOfFragments(numOfFragments).boundaryChars(boundaryChars).boundaryMaxScan(boundaryMaxScan) + .boundaryScannerType(boundaryScannerType).forceSource(forceSource).fragmenter(fragmenter) + .fragmentOffset(fragmentOffset).noMatchSize(noMatchSize).order(order).phraseLimit(phraseLimit)) + .encoder(encoder))); + searchRequestBuilder.highlighter(highlightBuilder); + } + + protected void buildSort(final QueryContext queryContext, final FessConfig fessConfig) { + queryContext.sortBuilders().forEach(sortBuilder -> searchRequestBuilder.addSort(sortBuilder)); + } + + protected void buildRescorer(final QueryHelper queryHelper, final FessConfig fessConfig) { + stream(queryHelper.getRescorers(condition())).of(stream -> stream.forEach(searchRequestBuilder::addRescorer)); + } + + protected QueryContext buildQueryContext(final QueryHelper queryHelper, final FessConfig fessConfig) { + return queryHelper.build( + searchRequestType, + query, + context -> { if (SearchRequestType.ADMIN_SEARCH.equals(searchRequestType)) { context.skipRoleQuery(); } else if (similarDocHash != null) { @@ -1126,77 +1234,6 @@ public class FessEsClient implements Client { }); } }); - - searchRequestBuilder.setFrom(offset).setSize(size); - - final Object trackTotalHitsValue = fessConfig.getQueryTrackTotalHitsValue(); - if (trackTotalHitsValue instanceof Boolean) { - searchRequestBuilder.setTrackTotalHits((Boolean) trackTotalHitsValue); - } else if (trackTotalHitsValue instanceof Number) { - searchRequestBuilder.setTrackTotalHitsUpTo(((Number) trackTotalHitsValue).intValue()); - } - - if (responseFields != null) { - searchRequestBuilder.setFetchSource(responseFields, null); - } - - // rescorer - stream(queryHelper.getRescorers(condition())).of(stream -> stream.forEach(searchRequestBuilder::addRescorer)); - - // sort - queryContext.sortBuilders().forEach(sortBuilder -> searchRequestBuilder.addSort(sortBuilder)); - - // highlighting - if (highlightInfo != null) { - final HighlightBuilder highlightBuilder = new HighlightBuilder(); - queryHelper.highlightedFields(stream -> stream.forEach(hf -> highlightBuilder.field(new HighlightBuilder.Field(hf) - .highlighterType(highlightInfo.getType()).fragmentSize(highlightInfo.getFragmentSize()) - .numOfFragments(highlightInfo.getNumOfFragments())))); - searchRequestBuilder.highlighter(highlightBuilder); - } - - // facets - if (facetInfo != null) { - stream(facetInfo.field).of( - stream -> stream.forEach(f -> { - if (queryHelper.isFacetField(f)) { - final String encodedField = BaseEncoding.base64().encode(f.getBytes(StandardCharsets.UTF_8)); - final TermsAggregationBuilder termsBuilder = - AggregationBuilders.terms(Constants.FACET_FIELD_PREFIX + encodedField).field(f); - termsBuilder.order(facetInfo.getBucketOrder()); - if (facetInfo.size != null) { - termsBuilder.size(facetInfo.size); - } - if (facetInfo.minDocCount != null) { - termsBuilder.minDocCount(facetInfo.minDocCount); - } - if (facetInfo.missing != null) { - termsBuilder.missing(facetInfo.missing); - } - searchRequestBuilder.addAggregation(termsBuilder); - } else { - throw new SearchQueryException("Invalid facet field: " + f); - } - })); - stream(facetInfo.query).of( - stream -> stream.forEach(fq -> { - final QueryContext facetContext = new QueryContext(fq, false); - queryHelper.buildBaseQuery(facetContext, c -> {}); - final String encodedFacetQuery = BaseEncoding.base64().encode(fq.getBytes(StandardCharsets.UTF_8)); - final FilterAggregationBuilder filterBuilder = - AggregationBuilders.filter(Constants.FACET_QUERY_PREFIX + encodedFacetQuery, - facetContext.getQueryBuilder()); - searchRequestBuilder.addAggregation(filterBuilder); - })); - } - - if (!SearchRequestType.ADMIN_SEARCH.equals(searchRequestType) && !isScroll && fessConfig.isResultCollapsed() - && similarDocHash == null) { - searchRequestBuilder.setCollapse(getCollapseBuilder(fessConfig)); - } - - searchRequestBuilder.setQuery(queryContext.getQueryBuilder()); - return true; } protected CollapseBuilder getCollapseBuilder(final FessConfig fessConfig) { diff --git a/src/main/java/org/codelibs/fess/es/config/exentity/CrawlingConfig.java b/src/main/java/org/codelibs/fess/es/config/exentity/CrawlingConfig.java index 247952ef7..9fd2614bf 100644 --- a/src/main/java/org/codelibs/fess/es/config/exentity/CrawlingConfig.java +++ b/src/main/java/org/codelibs/fess/es/config/exentity/CrawlingConfig.java @@ -67,7 +67,7 @@ public interface CrawlingConfig { public enum ConfigType { WEB("W"), FILE("F"), DATA("D"); - private String typePrefix; + private final String typePrefix; ConfigType(final String typePrefix) { this.typePrefix = typePrefix; diff --git a/src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java b/src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java index 1bf876854..c58ddabf8 100644 --- a/src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java +++ b/src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java @@ -83,7 +83,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -server - -Xms256m + -Xms128m -Xmx256m -XX:MaxMetaspaceSize=128m -XX:CompressedClassSpaceSize=32m @@ -114,7 +114,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction -Djdk.io.permissionsUseCanonicalPath=true -server -Xms128m - -Xmx128m + -Xmx256m -XX:MaxMetaspaceSize=128m -XX:CompressedClassSpaceSize=32m -XX:-UseGCOverheadLimit @@ -675,6 +675,36 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction /** The key of the configuration. e.g. </strong> */ String QUERY_HIGHLIGHT_TAG_POST = "query.highlight.tag.post"; + /** The key of the configuration. e.g. */ + String QUERY_HIGHLIGHT_BOUNDARY_CHARS = "query.highlight.boundary.chars"; + + /** The key of the configuration. e.g. 20 */ + String QUERY_HIGHLIGHT_BOUNDARY_MAX_SCAN = "query.highlight.boundary.max.scan"; + + /** The key of the configuration. e.g. sentence */ + String QUERY_HIGHLIGHT_BOUNDARY_SCANNER = "query.highlight.boundary.scanner"; + + /** The key of the configuration. e.g. default */ + String QUERY_HIGHLIGHT_ENCODER = "query.highlight.encoder"; + + /** The key of the configuration. e.g. false */ + String QUERY_HIGHLIGHT_FORCE_SOURCE = "query.highlight.force.source"; + + /** The key of the configuration. e.g. span */ + String QUERY_HIGHLIGHT_FRAGMENTER = "query.highlight.fragmenter"; + + /** The key of the configuration. e.g. -1 */ + String QUERY_HIGHLIGHT_FRAGMENT_OFFSET = "query.highlight.fragment.offset"; + + /** The key of the configuration. e.g. 0 */ + String QUERY_HIGHLIGHT_NO_MATCH_SIZE = "query.highlight.no.match.size"; + + /** The key of the configuration. e.g. score */ + String QUERY_HIGHLIGHT_ORDER = "query.highlight.order"; + + /** The key of the configuration. e.g. 256 */ + String QUERY_HIGHLIGHT_PHRASE_LIMIT = "query.highlight.phrase.limit"; + /** The key of the configuration. e.g. hl_content,digest */ String QUERY_HIGHLIGHT_CONTENT_DESCRIPTION_FIELDS = "query.highlight.content.description.fields"; @@ -1543,7 +1573,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -server - -Xms256m + -Xms128m -Xmx256m -XX:MaxMetaspaceSize=128m -XX:CompressedClassSpaceSize=32m @@ -1578,7 +1608,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction -Djdk.io.permissionsUseCanonicalPath=true -server -Xms128m - -Xmx128m + -Xmx256m -XX:MaxMetaspaceSize=128m -XX:CompressedClassSpaceSize=32m -XX:-UseGCOverheadLimit @@ -3422,6 +3452,123 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction */ String getQueryHighlightTagPost(); + /** + * Get the value for the key 'query.highlight.boundary.chars'.
+ * The value is, e.g.
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightBoundaryChars(); + + /** + * Get the value for the key 'query.highlight.boundary.chars' as {@link Integer}.
+ * The value is, e.g.
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + * @throws NumberFormatException When the property is not integer. + */ + Integer getQueryHighlightBoundaryCharsAsInteger(); + + /** + * Get the value for the key 'query.highlight.boundary.max.scan'.
+ * The value is, e.g. 20
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightBoundaryMaxScan(); + + /** + * Get the value for the key 'query.highlight.boundary.max.scan' as {@link Integer}.
+ * The value is, e.g. 20
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + * @throws NumberFormatException When the property is not integer. + */ + Integer getQueryHighlightBoundaryMaxScanAsInteger(); + + /** + * Get the value for the key 'query.highlight.boundary.scanner'.
+ * The value is, e.g. sentence
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightBoundaryScanner(); + + /** + * Get the value for the key 'query.highlight.encoder'.
+ * The value is, e.g. default
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightEncoder(); + + /** + * Get the value for the key 'query.highlight.force.source'.
+ * The value is, e.g. false
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightForceSource(); + + /** + * Is the property for the key 'query.highlight.force.source' true?
+ * The value is, e.g. false
+ * @return The determination, true or false. (if not found, exception but basically no way) + */ + boolean isQueryHighlightForceSource(); + + /** + * Get the value for the key 'query.highlight.fragmenter'.
+ * The value is, e.g. span
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightFragmenter(); + + /** + * Get the value for the key 'query.highlight.fragment.offset'.
+ * The value is, e.g. -1
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightFragmentOffset(); + + /** + * Get the value for the key 'query.highlight.fragment.offset' as {@link Integer}.
+ * The value is, e.g. -1
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + * @throws NumberFormatException When the property is not integer. + */ + Integer getQueryHighlightFragmentOffsetAsInteger(); + + /** + * Get the value for the key 'query.highlight.no.match.size'.
+ * The value is, e.g. 0
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightNoMatchSize(); + + /** + * Get the value for the key 'query.highlight.no.match.size' as {@link Integer}.
+ * The value is, e.g. 0
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + * @throws NumberFormatException When the property is not integer. + */ + Integer getQueryHighlightNoMatchSizeAsInteger(); + + /** + * Get the value for the key 'query.highlight.order'.
+ * The value is, e.g. score
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightOrder(); + + /** + * Get the value for the key 'query.highlight.phrase.limit'.
+ * The value is, e.g. 256
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + */ + String getQueryHighlightPhraseLimit(); + + /** + * Get the value for the key 'query.highlight.phrase.limit' as {@link Integer}.
+ * The value is, e.g. 256
+ * @return The value of found property. (NotNull: if not found, exception but basically no way) + * @throws NumberFormatException When the property is not integer. + */ + Integer getQueryHighlightPhraseLimitAsInteger(); + /** * Get the value for the key 'query.highlight.content.description.fields'.
* The value is, e.g. hl_content,digest
@@ -6992,6 +7139,70 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction return get(FessConfig.QUERY_HIGHLIGHT_TAG_POST); } + public String getQueryHighlightBoundaryChars() { + return get(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_CHARS); + } + + public Integer getQueryHighlightBoundaryCharsAsInteger() { + return getAsInteger(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_CHARS); + } + + public String getQueryHighlightBoundaryMaxScan() { + return get(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_MAX_SCAN); + } + + public Integer getQueryHighlightBoundaryMaxScanAsInteger() { + return getAsInteger(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_MAX_SCAN); + } + + public String getQueryHighlightBoundaryScanner() { + return get(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_SCANNER); + } + + public String getQueryHighlightEncoder() { + return get(FessConfig.QUERY_HIGHLIGHT_ENCODER); + } + + public String getQueryHighlightForceSource() { + return get(FessConfig.QUERY_HIGHLIGHT_FORCE_SOURCE); + } + + public boolean isQueryHighlightForceSource() { + return is(FessConfig.QUERY_HIGHLIGHT_FORCE_SOURCE); + } + + public String getQueryHighlightFragmenter() { + return get(FessConfig.QUERY_HIGHLIGHT_FRAGMENTER); + } + + public String getQueryHighlightFragmentOffset() { + return get(FessConfig.QUERY_HIGHLIGHT_FRAGMENT_OFFSET); + } + + public Integer getQueryHighlightFragmentOffsetAsInteger() { + return getAsInteger(FessConfig.QUERY_HIGHLIGHT_FRAGMENT_OFFSET); + } + + public String getQueryHighlightNoMatchSize() { + return get(FessConfig.QUERY_HIGHLIGHT_NO_MATCH_SIZE); + } + + public Integer getQueryHighlightNoMatchSizeAsInteger() { + return getAsInteger(FessConfig.QUERY_HIGHLIGHT_NO_MATCH_SIZE); + } + + public String getQueryHighlightOrder() { + return get(FessConfig.QUERY_HIGHLIGHT_ORDER); + } + + public String getQueryHighlightPhraseLimit() { + return get(FessConfig.QUERY_HIGHLIGHT_PHRASE_LIMIT); + } + + public Integer getQueryHighlightPhraseLimitAsInteger() { + return getAsInteger(FessConfig.QUERY_HIGHLIGHT_PHRASE_LIMIT); + } + public String getQueryHighlightContentDescriptionFields() { return get(FessConfig.QUERY_HIGHLIGHT_CONTENT_DESCRIPTION_FIELDS); } @@ -8353,10 +8564,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction "-Djava.awt.headless=true\n-Dfile.encoding=UTF-8\n-Djna.nosys=true\n-Djdk.io.permissionsUseCanonicalPath=true\n-Dhttp.maxConnections=20\n-server\n-Xms512m\n-Xmx512m\n-XX:MaxMetaspaceSize=128m\n-XX:CompressedClassSpaceSize=32m\n-XX:-UseGCOverheadLimit\n-XX:+UseTLAB\n-XX:+DisableExplicitGC\n-XX:+HeapDumpOnOutOfMemoryError\n-XX:-OmitStackTraceInFastThrow\n-XX:+UnlockExperimentalVMOptions\n-XX:+UseG1GC\n-XX:InitiatingHeapOccupancyPercent=45\n-XX:G1HeapRegionSize=1m\n-XX:MaxGCPauseMillis=60000\n-XX:G1NewSizePercent=5\n-XX:G1MaxNewSizePercent=5\n-Djcifs.smb.client.responseTimeout=30000\n-Djcifs.smb.client.soTimeout=35000\n-Djcifs.smb.client.connTimeout=60000\n-Djcifs.smb.client.sessionTimeout=60000\n-Djcifs.smb1.smb.client.connTimeout=60000\n-Djcifs.smb1.smb.client.soTimeout=35000\n-Djcifs.smb1.smb.client.responseTimeout=30000\n-Dgroovy.use.classvalue=true\n-Dio.netty.noUnsafe=true\n-Dio.netty.noKeySetOptimization=true\n-Dio.netty.recycler.maxCapacityPerThread=0\n-Dlog4j.shutdownHookEnabled=false\n-Dlog4j2.disable.jmx=true\n-Dlog4j.skipJansi=true\n-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider\n-Dorg.apache.pdfbox.rendering.UsePureJavaCMYKConversion=true\n"); defaultMap .put(FessConfig.JVM_SUGGEST_OPTIONS, - "-Djava.awt.headless=true\n-Dfile.encoding=UTF-8\n-Djna.nosys=true\n-Djdk.io.permissionsUseCanonicalPath=true\n-server\n-Xms256m\n-Xmx256m\n-XX:MaxMetaspaceSize=128m\n-XX:CompressedClassSpaceSize=32m\n-XX:-UseGCOverheadLimit\n-XX:+UseTLAB\n-XX:+DisableExplicitGC\n-XX:+HeapDumpOnOutOfMemoryError\n-XX:+UnlockExperimentalVMOptions\n-XX:+UseG1GC\n-XX:InitiatingHeapOccupancyPercent=45\n-XX:G1HeapRegionSize=1m\n-XX:MaxGCPauseMillis=60000\n-XX:G1NewSizePercent=5\n-XX:G1MaxNewSizePercent=30\n-Dgroovy.use.classvalue=true\n-Dio.netty.noUnsafe=true\n-Dio.netty.noKeySetOptimization=true\n-Dio.netty.recycler.maxCapacityPerThread=0\n-Dlog4j.shutdownHookEnabled=false\n-Dlog4j2.disable.jmx=true\n-Dlog4j.skipJansi=true\n"); + "-Djava.awt.headless=true\n-Dfile.encoding=UTF-8\n-Djna.nosys=true\n-Djdk.io.permissionsUseCanonicalPath=true\n-server\n-Xms128m\n-Xmx256m\n-XX:MaxMetaspaceSize=128m\n-XX:CompressedClassSpaceSize=32m\n-XX:-UseGCOverheadLimit\n-XX:+UseTLAB\n-XX:+DisableExplicitGC\n-XX:+HeapDumpOnOutOfMemoryError\n-XX:+UnlockExperimentalVMOptions\n-XX:+UseG1GC\n-XX:InitiatingHeapOccupancyPercent=45\n-XX:G1HeapRegionSize=1m\n-XX:MaxGCPauseMillis=60000\n-XX:G1NewSizePercent=5\n-XX:G1MaxNewSizePercent=30\n-Dgroovy.use.classvalue=true\n-Dio.netty.noUnsafe=true\n-Dio.netty.noKeySetOptimization=true\n-Dio.netty.recycler.maxCapacityPerThread=0\n-Dlog4j.shutdownHookEnabled=false\n-Dlog4j2.disable.jmx=true\n-Dlog4j.skipJansi=true\n"); defaultMap .put(FessConfig.JVM_THUMBNAIL_OPTIONS, - "-Djava.awt.headless=true\n-Dfile.encoding=UTF-8\n-Djna.nosys=true\n-Djdk.io.permissionsUseCanonicalPath=true\n-server\n-Xms128m\n-Xmx128m\n-XX:MaxMetaspaceSize=128m\n-XX:CompressedClassSpaceSize=32m\n-XX:-UseGCOverheadLimit\n-XX:+UseTLAB\n-XX:+DisableExplicitGC\n-XX:+HeapDumpOnOutOfMemoryError\n-XX:-OmitStackTraceInFastThrow\n-XX:+UnlockExperimentalVMOptions\n-XX:+UseG1GC\n-XX:InitiatingHeapOccupancyPercent=45\n-XX:G1HeapRegionSize=4m\n-XX:MaxGCPauseMillis=60000\n-XX:G1NewSizePercent=5\n-XX:G1MaxNewSizePercent=50\n-Djcifs.smb.client.responseTimeout=30000\n-Djcifs.smb.client.soTimeout=35000\n-Djcifs.smb.client.connTimeout=60000\n-Djcifs.smb.client.sessionTimeout=60000\n-Djcifs.smb1.smb.client.connTimeout=60000\n-Djcifs.smb1.smb.client.soTimeout=35000\n-Djcifs.smb1.smb.client.responseTimeout=30000\n-Dgroovy.use.classvalue=true\n-Dio.netty.noUnsafe=true\n-Dio.netty.noKeySetOptimization=true\n-Dio.netty.recycler.maxCapacityPerThread=0\n-Dlog4j.shutdownHookEnabled=false\n-Dlog4j2.disable.jmx=true\n-Dlog4j.skipJansi=true\n-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider\n-Dorg.apache.pdfbox.rendering.UsePureJavaCMYKConversion=true\n"); + "-Djava.awt.headless=true\n-Dfile.encoding=UTF-8\n-Djna.nosys=true\n-Djdk.io.permissionsUseCanonicalPath=true\n-server\n-Xms128m\n-Xmx256m\n-XX:MaxMetaspaceSize=128m\n-XX:CompressedClassSpaceSize=32m\n-XX:-UseGCOverheadLimit\n-XX:+UseTLAB\n-XX:+DisableExplicitGC\n-XX:+HeapDumpOnOutOfMemoryError\n-XX:-OmitStackTraceInFastThrow\n-XX:+UnlockExperimentalVMOptions\n-XX:+UseG1GC\n-XX:InitiatingHeapOccupancyPercent=45\n-XX:G1HeapRegionSize=4m\n-XX:MaxGCPauseMillis=60000\n-XX:G1NewSizePercent=5\n-XX:G1MaxNewSizePercent=50\n-Djcifs.smb.client.responseTimeout=30000\n-Djcifs.smb.client.soTimeout=35000\n-Djcifs.smb.client.connTimeout=60000\n-Djcifs.smb.client.sessionTimeout=60000\n-Djcifs.smb1.smb.client.connTimeout=60000\n-Djcifs.smb1.smb.client.soTimeout=35000\n-Djcifs.smb1.smb.client.responseTimeout=30000\n-Dgroovy.use.classvalue=true\n-Dio.netty.noUnsafe=true\n-Dio.netty.noKeySetOptimization=true\n-Dio.netty.recycler.maxCapacityPerThread=0\n-Dlog4j.shutdownHookEnabled=false\n-Dlog4j2.disable.jmx=true\n-Dlog4j.skipJansi=true\n-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider\n-Dorg.apache.pdfbox.rendering.UsePureJavaCMYKConversion=true\n"); defaultMap.put(FessConfig.JOB_SYSTEM_JOB_IDS, "default_crawler"); defaultMap.put(FessConfig.JOB_TEMPLATE_TITLE_WEB, "Web Crawler - {0}"); defaultMap.put(FessConfig.JOB_TEMPLATE_TITLE_FILE, "File Crawler - {0}"); @@ -8538,6 +8749,16 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction defaultMap.put(FessConfig.QUERY_HIGHLIGHT_TYPE, "fvh"); defaultMap.put(FessConfig.QUERY_HIGHLIGHT_TAG_PRE, ""); defaultMap.put(FessConfig.QUERY_HIGHLIGHT_TAG_POST, ""); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_CHARS, "\t\n "); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_MAX_SCAN, "20"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_BOUNDARY_SCANNER, "sentence"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_ENCODER, "default"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_FORCE_SOURCE, "false"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_FRAGMENTER, "span"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_FRAGMENT_OFFSET, "-1"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_NO_MATCH_SIZE, "0"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_ORDER, "score"); + defaultMap.put(FessConfig.QUERY_HIGHLIGHT_PHRASE_LIMIT, "256"); defaultMap.put(FessConfig.QUERY_HIGHLIGHT_CONTENT_DESCRIPTION_FIELDS, "hl_content,digest"); defaultMap.put(FessConfig.QUERY_MAX_SEARCH_RESULT_OFFSET, "100000"); defaultMap.put(FessConfig.QUERY_ADDITIONAL_DEFAULT_FIELDS, ""); diff --git a/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java b/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java index 7efc4c5a9..19fe0643c 100644 --- a/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java +++ b/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java @@ -71,6 +71,8 @@ import org.lastaflute.web.validation.theme.typed.LongTypeValidator; public interface FessProp { + String QUERY_HIGHLIGHT_BOUNDARY_CHARS = "queryHighlightBoundaryChars"; + String QUERY_TRACK_TOTAL_HITS_VALUE = "queryTrackTotalHitsValue"; String CORS_ALLOW_ORIGIN = "CorsAllowOrigin"; @@ -2022,4 +2024,20 @@ public interface FessProp { } return pattern.matcher(version).matches(); } + + String getQueryHighlightBoundaryChars(); + + default char[] getQueryHighlightBoundaryCharsAsArray() { + char[] chars = (char[]) propMap.get(QUERY_HIGHLIGHT_BOUNDARY_CHARS); + if (chars == null) { + final String value = getQueryHighlightBoundaryChars(); + chars = new char[value.length()]; + for (int i = 0; i < value.length(); i++) { + chars[i] = value.charAt(i); + } + propMap.put(QUERY_HIGHLIGHT_BOUNDARY_CHARS, chars); + } + return chars; + } + } diff --git a/src/main/resources/fess_config.properties b/src/main/resources/fess_config.properties index 4b52cda16..b99860ce0 100644 --- a/src/main/resources/fess_config.properties +++ b/src/main/resources/fess_config.properties @@ -340,6 +340,16 @@ query.highlight.number.of.fragments=2 query.highlight.type=fvh query.highlight.tag.pre= query.highlight.tag.post= +query.highlight.boundary.chars=\u0009\u000A\u0013\u0020 +query.highlight.boundary.max.scan=20 +query.highlight.boundary.scanner=sentence +query.highlight.encoder=default +query.highlight.force.source=false +query.highlight.fragmenter=span +query.highlight.fragment.offset=-1 +query.highlight.no.match.size=0 +query.highlight.order=score +query.highlight.phrase.limit=256 query.highlight.content.description.fields=hl_content,digest query.max.search.result.offset=100000 query.additional.default.fields=