diff --git a/src/main/java/org/codelibs/fess/entity/QueryContext.java b/src/main/java/org/codelibs/fess/entity/QueryContext.java index 931830e74..d964da06e 100644 --- a/src/main/java/org/codelibs/fess/entity/QueryContext.java +++ b/src/main/java/org/codelibs/fess/entity/QueryContext.java @@ -26,7 +26,9 @@ import java.util.Map; import java.util.Set; import java.util.function.Consumer; +import org.codelibs.core.lang.StringUtil; import org.codelibs.fess.Constants; +import org.codelibs.fess.util.ComponentUtil; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; @@ -36,11 +38,16 @@ import org.elasticsearch.search.sort.SortBuilder; import org.lastaflute.web.util.LaRequestUtil; public class QueryContext { + + protected static final String ALLINURL_FIELD_PREFIX = "allinurl:"; + + protected static final String ALLINTITLE_FIELD_PREFIX = "allintitle:"; + private QueryBuilder queryBuilder; private final List> sortBuilderList = new ArrayList<>(); - private final String queryString; + private String queryString; private Set highlightedQuerySet = null; @@ -48,9 +55,26 @@ public class QueryContext { private boolean disableRoleQuery = false; + private String defaultField = null; + @SuppressWarnings("unchecked") public QueryContext(final String queryString, final boolean isQuery) { - this.queryString = queryString; + if (queryString != null) { + if (queryString.startsWith(ALLINURL_FIELD_PREFIX)) { + this.defaultField = ComponentUtil.getFessConfig().getIndexFieldUrl(); + this.queryString = queryString.substring(ALLINURL_FIELD_PREFIX.length()); + } else if (queryString.startsWith(ALLINTITLE_FIELD_PREFIX)) { + this.defaultField = ComponentUtil.getFessConfig().getIndexFieldTitle(); + this.queryString = queryString.substring(ALLINTITLE_FIELD_PREFIX.length()); + } else { + this.queryString = queryString; + } + } else { + this.queryString = queryString; + } + if (StringUtil.isBlank(this.queryString)) { + this.queryString = "*"; + } if (isQuery) { LaRequestUtil.getOptionalRequest().ifPresent(request -> { highlightedQuerySet = new HashSet<>(); @@ -140,4 +164,12 @@ public class QueryContext { public void skipRoleQuery() { disableRoleQuery = true; } + + public String getDefaultField() { + return defaultField; + } + + public void setDefaultField(String defaultField) { + this.defaultField = defaultField; + } } diff --git a/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java b/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java index a719da3ea..cefb96aaa 100644 --- a/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java +++ b/src/main/java/org/codelibs/fess/entity/SearchRequestParams.java @@ -36,6 +36,10 @@ public interface SearchRequestParams { String AS_FILETYPE = "filetype"; + String AS_SITESEARCH = "sitesearch"; + + String AS_OCCURRENCE = "occt"; + String getQuery(); Map getFields(); @@ -70,6 +74,7 @@ public interface SearchRequestParams { || !isEmptyArray(conditions.get(AS_EPQ))// || !isEmptyArray(conditions.get(AS_OQ))// || !isEmptyArray(conditions.get(AS_NQ))// + || !isEmptyArray(conditions.get(AS_SITESEARCH))// || !isEmptyArray(conditions.get(AS_FILETYPE)); } diff --git a/src/main/java/org/codelibs/fess/helper/QueryHelper.java b/src/main/java/org/codelibs/fess/helper/QueryHelper.java index 1ee4d3016..21885c47d 100644 --- a/src/main/java/org/codelibs/fess/helper/QueryHelper.java +++ b/src/main/java/org/codelibs/fess/helper/QueryHelper.java @@ -82,6 +82,8 @@ public class QueryHelper { protected static final String INURL_FIELD = "inurl"; + protected static final String SITE_FIELD = "site"; + @Resource protected FessConfig fessConfig; @@ -193,6 +195,7 @@ public class QueryHelper { fessConfig.getIndexFieldUrl(), // fessConfig.getIndexFieldDocId(), // fessConfig.getIndexFieldHost(), // + fessConfig.getIndexFieldSite(), // fessConfig.getIndexFieldTitle(), // fessConfig.getIndexFieldContent(), // fessConfig.getIndexFieldContentLength(), // @@ -415,7 +418,10 @@ public class QueryHelper { } } } - return boolQuery; + if (boolQuery.hasClauses()) { + return boolQuery; + } + return null; } protected String toLowercaseWildcard(final String value) { @@ -425,8 +431,15 @@ public class QueryHelper { return value; } + protected String getSearchField(final QueryContext context, final String field) { + if (Constants.DEFAULT_FIELD.equals(field) && context.getDefaultField() != null) { + return context.getDefaultField(); + } + return field; + } + protected QueryBuilder convertWildcardQuery(final QueryContext context, final WildcardQuery wildcardQuery, final float boost) { - final String field = wildcardQuery.getField(); + final String field = getSearchField(context, wildcardQuery.getField()); if (Constants.DEFAULT_FIELD.equals(field)) { context.addFieldLog(field, wildcardQuery.getTerm().text()); return buildDefaultQueryBuilder((f, b) -> QueryBuilders.wildcardQuery(f, toLowercaseWildcard(wildcardQuery.getTerm().text())) @@ -444,7 +457,7 @@ public class QueryHelper { } protected QueryBuilder convertPrefixQuery(final QueryContext context, final PrefixQuery prefixQuery, final float boost) { - final String field = prefixQuery.getField(); + final String field = getSearchField(context, prefixQuery.getField()); if (Constants.DEFAULT_FIELD.equals(field)) { context.addFieldLog(field, prefixQuery.getPrefix().text()); return buildDefaultQueryBuilder((f, b) -> QueryBuilders.prefixQuery(f, toLowercaseWildcard(prefixQuery.getPrefix().text())) @@ -463,7 +476,7 @@ public class QueryHelper { protected QueryBuilder convertFuzzyQuery(final QueryContext context, final FuzzyQuery fuzzyQuery, final float boost) { final Term term = fuzzyQuery.getTerm(); - final String field = term.field(); + final String field = getSearchField(context, term.field()); // TODO fuzzy value if (Constants.DEFAULT_FIELD.equals(field)) { context.addFieldLog(field, term.text()); @@ -482,7 +495,7 @@ public class QueryHelper { } protected QueryBuilder convertTermRangeQuery(final QueryContext context, final TermRangeQuery termRangeQuery, final float boost) { - final String field = termRangeQuery.getField(); + final String field = getSearchField(context, termRangeQuery.getField()); if (isSearchField(field)) { context.addFieldLog(field, termRangeQuery.toString(field)); final RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(field); @@ -530,7 +543,7 @@ public class QueryHelper { } protected QueryBuilder convertTermQuery(final QueryContext context, final TermQuery termQuery, final float boost) { - final String field = termQuery.getTerm().field(); + final String field = getSearchField(context, termQuery.getTerm().field()); final String text = termQuery.getTerm().text(); if (fessConfig.getQueryReplaceTermWithPrefixQueryAsBoolean() && text.length() > 1 && text.endsWith("*")) { return convertPrefixQuery(context, new PrefixQuery(new Term(field, text.substring(0, text.length() - 1))), boost); @@ -562,8 +575,10 @@ public class QueryHelper { } context.addSorts(createFieldSortBuilder(sortField, sortOrder)); return null; - } else if (INURL_FIELD.equals(field)) { + } else if (INURL_FIELD.equals(field) || fessConfig.getIndexFieldUrl().equals(context.getDefaultField())) { return QueryBuilders.wildcardQuery(fessConfig.getIndexFieldUrl(), "*" + text + "*").boost(boost); + } else if (SITE_FIELD.equals(field)) { + return convertSiteQuery(context, text, boost); } else if (isSearchField(field)) { context.addFieldLog(field, text); context.addHighlightedQuery(text); @@ -580,6 +595,10 @@ public class QueryHelper { } } + protected QueryBuilder convertSiteQuery(final QueryContext context, final String text, final float boost) { + return QueryBuilders.prefixQuery(fessConfig.getIndexFieldSite(), text).boost(boost); + } + private QueryBuilder convertPhraseQuery(final QueryContext context, final PhraseQuery query, final float boost) { final Term[] terms = query.getTerms(); if (terms.length == 0) { diff --git a/src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java b/src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java index 15dbeff44..972f260f1 100644 --- a/src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java +++ b/src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java @@ -2718,6 +2718,21 @@ public class FessLabels extends UserMessages { /** The key of the message: MS PowerPoint */ public static final String LABELS_advance_search_filetype_powerpoint = "{labels.advance_search_filetype_powerpoint}"; + /** The key of the message: Terms appearing */ + public static final String LABELS_advance_search_occt = "{labels.advance_search_occt}"; + + /** The key of the message: anywhere in the page */ + public static final String LABELS_advance_search_occt_default = "{labels.advance_search_occt_default}"; + + /** The key of the message: in the title of the page */ + public static final String LABELS_advance_search_occt_allintitle = "{labels.advance_search_occt_allintitle}"; + + /** The key of the message: in the url of the page */ + public static final String LABELS_advance_search_occt_allinurl = "{labels.advance_search_occt_allinurl}"; + + /** The key of the message: Site or domain */ + public static final String LABELS_advance_search_sitesearch = "{labels.advance_search_sitesearch}"; + /** * Assert the property is not null. * @param property The value of the property. (NotNull) diff --git a/src/main/java/org/codelibs/fess/util/QueryStringBuilder.java b/src/main/java/org/codelibs/fess/util/QueryStringBuilder.java index a49b8731d..128bc0f7a 100644 --- a/src/main/java/org/codelibs/fess/util/QueryStringBuilder.java +++ b/src/main/java/org/codelibs/fess/util/QueryStringBuilder.java @@ -104,6 +104,9 @@ public class QueryStringBuilder { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final int maxQueryLength = fessConfig.getQueryMaxLengthAsInteger().intValue(); + stream(conditions.get(SearchRequestParams.AS_OCCURRENCE)).of( + stream -> stream.filter(q -> isOccurrence(q)).findFirst().ifPresent(q -> queryBuf.insert(0, q + ":"))); + stream(conditions.get(SearchRequestParams.AS_Q)).of( stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach( q -> queryBuf.append(' ').append(q))); @@ -127,10 +130,16 @@ public class QueryStringBuilder { stream(conditions.get(SearchRequestParams.AS_FILETYPE)).of( stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach( q -> queryBuf.append(" filetype:\"").append(q.trim()).append('"'))); - + stream(conditions.get(SearchRequestParams.AS_SITESEARCH)).of( + stream -> stream.filter(q -> StringUtil.isNotBlank(q) && q.length() <= maxQueryLength).forEach( + q -> queryBuf.append(" site:").append(q.trim()))); } - private String escape(final String q, final String... values) { + protected boolean isOccurrence(final String value) { + return "allintitle".equals(value) || "allinurl".equals(value); + } + + protected String escape(final String q, final String... values) { String value = q; for (String s : values) { value = value.replace(s, "\\" + s); diff --git a/src/main/resources/fess_label.properties b/src/main/resources/fess_label.properties index 6a091596d..a3035c703 100644 --- a/src/main/resources/fess_label.properties +++ b/src/main/resources/fess_label.properties @@ -896,3 +896,8 @@ labels.advance_search_filetype_pdf=PDF labels.advance_search_filetype_word=MS Word labels.advance_search_filetype_excel=MS Excel labels.advance_search_filetype_powerpoint=MS PowerPoint +labels.advance_search_occt=Terms appearing +labels.advance_search_occt_default=anywhere in the page +labels.advance_search_occt_allintitle=in the title of the page +labels.advance_search_occt_allinurl=in the url of the page +labels.advance_search_sitesearch=Site or domain diff --git a/src/main/resources/fess_label_en.properties b/src/main/resources/fess_label_en.properties index f58f851f2..dd7f04703 100644 --- a/src/main/resources/fess_label_en.properties +++ b/src/main/resources/fess_label_en.properties @@ -896,3 +896,8 @@ labels.advance_search_filetype_pdf=PDF labels.advance_search_filetype_word=MS Word labels.advance_search_filetype_excel=MS Excel labels.advance_search_filetype_powerpoint=MS PowerPoint +labels.advance_search_occt=Terms appearing +labels.advance_search_occt_default=anywhere in the page +labels.advance_search_occt_allintitle=in the title of the page +labels.advance_search_occt_allinurl=in the url of the page +labels.advance_search_sitesearch=Site or domain diff --git a/src/main/resources/fess_label_ja.properties b/src/main/resources/fess_label_ja.properties index af13c9511..ba889fde6 100644 --- a/src/main/resources/fess_label_ja.properties +++ b/src/main/resources/fess_label_ja.properties @@ -898,3 +898,8 @@ labels.advance_search_filetype_pdf=PDF labels.advance_search_filetype_word=MS Word labels.advance_search_filetype_excel=MS Excel labels.advance_search_filetype_powerpoint=MS PowerPoint +labels.advance_search_occt=\u691c\u7d22\u5bfe\u8c61 +labels.advance_search_occt_default=\u30da\u30fc\u30b8\u5168\u4f53 +labels.advance_search_occt_allintitle=\u30da\u30fc\u30b8\u5185\u306e\u30bf\u30a4\u30c8\u30eb +labels.advance_search_occt_allinurl=\u30da\u30fc\u30b8\u5185\u306eURL +labels.advance_search_sitesearch=\u30b5\u30a4\u30c8\u307e\u305f\u306f\u30c9\u30e1\u30a4\u30f3 diff --git a/src/main/webapp/WEB-INF/view/advance.jsp b/src/main/webapp/WEB-INF/view/advance.jsp index 8da7b4fcb..830dc5117 100644 --- a/src/main/webapp/WEB-INF/view/advance.jsp +++ b/src/main/webapp/WEB-INF/view/advance.jsp @@ -239,7 +239,7 @@ />
+ + + + +
+
+ +
+ +
+ +
+ +
+
+ +
+