Ver código fonte

rename request parameters

Shinsuke Sugaya 9 anos atrás
pai
commit
875468db7f
27 arquivos alterados com 371 adições e 561 exclusões
  1. 1 5
      src/main/java/org/codelibs/fess/Constants.java
  2. 19 22
      src/main/java/org/codelibs/fess/api/json/JsonApiManager.java
  3. 1 1
      src/main/java/org/codelibs/fess/api/suggest/SuggestApiManager.java
  4. 7 99
      src/main/java/org/codelibs/fess/app/service/SearchService.java
  5. 2 2
      src/main/java/org/codelibs/fess/app/web/admin/searchlist/AdminSearchlistAction.java
  6. 17 26
      src/main/java/org/codelibs/fess/app/web/admin/searchlist/ListForm.java
  7. 7 23
      src/main/java/org/codelibs/fess/app/web/search/SearchAction.java
  8. 14 23
      src/main/java/org/codelibs/fess/app/web/search/SearchForm.java
  9. 2 2
      src/main/java/org/codelibs/fess/entity/FacetInfo.java
  10. 2 4
      src/main/java/org/codelibs/fess/entity/SearchRequestParams.java
  11. 5 2
      src/main/java/org/codelibs/fess/es/client/FessEsClient.java
  12. 68 248
      src/main/java/org/codelibs/fess/helper/QueryHelper.java
  13. 108 0
      src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java
  14. 0 26
      src/main/java/org/codelibs/fess/util/MoreLikeThisResponse.java
  15. 78 0
      src/main/java/org/codelibs/fess/util/QueryStringBuilder.java
  16. 0 53
      src/main/java/org/codelibs/fess/util/QueryUtil.java
  17. 11 0
      src/main/java/org/codelibs/fess/util/StreamUtil.java
  18. 0 4
      src/main/resources/app.xml
  19. 8 0
      src/main/resources/fess_config.properties
  20. 1 1
      src/main/webapp/WEB-INF/view/admin/crawlinginfo/admin_crawlinginfo_details.jsp
  21. 7 7
      src/main/webapp/WEB-INF/view/admin/searchlist/admin_searchlist.jsp
  22. 1 1
      src/main/webapp/WEB-INF/view/common/admin/sidebar.jsp
  23. 1 1
      src/main/webapp/WEB-INF/view/error/header.jsp
  24. 1 1
      src/main/webapp/WEB-INF/view/header.jsp
  25. 2 2
      src/main/webapp/WEB-INF/view/index.jsp
  26. 1 1
      src/main/webapp/WEB-INF/view/search.jsp
  27. 7 7
      src/main/webapp/WEB-INF/view/searchResults.jsp

+ 1 - 5
src/main/java/org/codelibs/fess/Constants.java

@@ -134,8 +134,6 @@ public class Constants extends CoreLibConstants {
 
     public static final String SEARCH_DESKTOP_PROPERTY = "search.desktop";
 
-    public static final String SEARCH_RESULT_MAX_PAGE_SIZE = "search.result.max_page_size";
-
     public static final String NOTIFICATION_TO_PROPERTY = "notification.to";
 
     public static final String USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY = "search.use.browser.locale";
@@ -239,7 +237,7 @@ public class Constants extends CoreLibConstants {
 
     public static final String USER_CODE = "userCode";
 
-    public static final String SEARCH_FIELD_LOG_SEARCH_QUERY = "query";
+    public static final String SEARCH_FIELD_LOG_SEARCH_QUERY = "q";
 
     public static final String STATS_REPORT_TYPE = "reportType";
 
@@ -288,8 +286,6 @@ public class Constants extends CoreLibConstants {
 
     public static final String ALL_LANGUAGES = "all";
 
-    public static final String DEFAULT_OPERATOR = "defaultOperator";
-
     public static final String INVALID_NUMERIC_PARAMETER = "-1";
 
     public static final String FACET_FIELD_PREFIX = "field:";

+ 19 - 22
src/main/java/org/codelibs/fess/api/json/JsonApiManager.java

@@ -20,6 +20,7 @@ import java.io.StringWriter;
 import java.net.URLDecoder;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -48,7 +49,6 @@ import org.codelibs.fess.exception.WebApiException;
 import org.codelibs.fess.helper.HotSearchWordHelper;
 import org.codelibs.fess.helper.HotSearchWordHelper.Range;
 import org.codelibs.fess.helper.LabelTypeHelper;
-import org.codelibs.fess.helper.QueryHelper;
 import org.codelibs.fess.helper.SystemHelper;
 import org.codelibs.fess.helper.UserInfoHelper;
 import org.codelibs.fess.mylasta.direction.FessConfig;
@@ -134,6 +134,7 @@ public class JsonApiManager extends BaseApiManager {
 
     protected void processSearchRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
         final SearchService searchService = ComponentUtil.getComponent(SearchService.class);
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
 
         int status = 0;
         String errMsg = StringUtil.EMPTY;
@@ -142,7 +143,7 @@ public class JsonApiManager extends BaseApiManager {
         request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE, Constants.SEARCH_LOG_ACCESS_TYPE_JSON);
         try {
             final SearchRenderData data = new SearchRenderData();
-            final SearchApiRequestParams params = new SearchApiRequestParams(request);
+            final SearchApiRequestParams params = new SearchApiRequestParams(request, fessConfig);
             searchService.search(request, params, data);
             query = params.getQuery();
             final String execTime = data.getExecTime();
@@ -154,7 +155,7 @@ public class JsonApiManager extends BaseApiManager {
             final List<Map<String, Object>> documentItems = data.getDocumentItems();
             final FacetResponse facetResponse = data.getFacetResponse();
 
-            buf.append("\"query\":");
+            buf.append("\"q\":");
             buf.append(escapeJson(query));
             buf.append(",\"execTime\":");
             buf.append(execTime);
@@ -235,7 +236,7 @@ public class JsonApiManager extends BaseApiManager {
                     }
                     buf.append(']');
                 }
-                // facet query
+                // facet q
                 if (facetResponse.getQueryCountMap() != null) {
                     buf.append(',');
                     buf.append("\"facetQuery\":[");
@@ -671,33 +672,31 @@ public class JsonApiManager extends BaseApiManager {
 
         private final HttpServletRequest request;
 
+        private FessConfig fessConfig;
+
         private int startPosition = -1;
 
         private int pageSize = -1;
 
-        protected SearchApiRequestParams(final HttpServletRequest request) {
+        protected SearchApiRequestParams(final HttpServletRequest request, FessConfig fessConfig) {
             this.request = request;
+            this.fessConfig = fessConfig;
         }
 
         @Override
         public String getQuery() {
-            return request.getParameter("query");
-        }
-
-        @Override
-        public String getOperator() {
-            return request.getParameter("op");
+            return request.getParameter("q");
         }
 
         @Override
-        public String[] getAdditional() {
-            return request.getParameterValues("additional");
+        public String[] getExtraQueries() {
+            return request.getParameterValues("ex_q");
         }
 
         @Override
         public Map<String, String[]> getFields() {
             // TODO Auto-generated method stub
-            return new HashMap<>();
+            return Collections.emptyMap();
         }
 
         @Override
@@ -729,14 +728,13 @@ public class JsonApiManager extends BaseApiManager {
             }
 
             final String start = request.getParameter("start");
-            final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
             if (StringUtil.isBlank(start)) {
-                startPosition = queryHelper.getDefaultStart();
+                startPosition = fessConfig.getPagingSearchPageStartAsInteger();
             } else {
                 try {
                     startPosition = Integer.parseInt(start);
                 } catch (final NumberFormatException e) {
-                    startPosition = queryHelper.getDefaultStart();
+                    startPosition = fessConfig.getPagingSearchPageStartAsInteger();
                 }
             }
             return startPosition;
@@ -749,17 +747,16 @@ public class JsonApiManager extends BaseApiManager {
             }
 
             final String num = request.getParameter("num");
-            final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
             if (StringUtil.isBlank(num)) {
-                pageSize = queryHelper.getDefaultPageSize();
+                pageSize = fessConfig.getPagingSearchPageSizeAsInteger();
             } else {
                 try {
                     pageSize = Integer.parseInt(num);
-                    if (pageSize > queryHelper.getMaxPageSize() || pageSize <= 0) {
-                        pageSize = queryHelper.getMaxPageSize();
+                    if (pageSize > fessConfig.getPagingSearchPageMaxSizeAsInteger().intValue() || pageSize <= 0) {
+                        pageSize = fessConfig.getPagingSearchPageMaxSizeAsInteger();
                     }
                 } catch (final NumberFormatException e) {
-                    pageSize = queryHelper.getDefaultPageSize();
+                    pageSize = fessConfig.getPagingSearchPageSizeAsInteger();
                 }
             }
             return pageSize;

+ 1 - 1
src/main/java/org/codelibs/fess/api/suggest/SuggestApiManager.java

@@ -147,7 +147,7 @@ public class SuggestApiManager extends BaseApiManager {
         }
 
         protected static RequestParameter parse(final HttpServletRequest request) {
-            final String query = request.getParameter("query");
+            final String query = request.getParameter("q");
             final String fieldsStr = request.getParameter("fields");
             final String[] fields;
             if (StringUtils.isNotBlank(fieldsStr)) {

+ 7 - 99
src/main/java/org/codelibs/fess/app/service/SearchService.java

@@ -25,8 +25,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.function.Consumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
@@ -50,7 +48,7 @@ import org.codelibs.fess.helper.UserInfoHelper;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.QueryResponseList;
-import org.codelibs.fess.util.QueryUtil;
+import org.codelibs.fess.util.QueryStringBuilder;
 import org.dbflute.optional.OptionalEntity;
 import org.dbflute.util.DfTypeUtil;
 import org.elasticsearch.ElasticsearchException;
@@ -66,8 +64,6 @@ public class SearchService {
     //                                                                            Constant
     //
 
-    protected static final Pattern FIELD_EXTRACTION_PATTERN = Pattern.compile("^([a-zA-Z0-9_]+):.*");
-
     // ===================================================================================
     //                                                                           Attribute
     //
@@ -100,34 +96,8 @@ public class SearchService {
         final boolean searchLogSupport =
                 Constants.TRUE.equals(crawlerProperties.getProperty(Constants.SEARCH_LOG_PROPERTY, Constants.TRUE));
 
-        if (StringUtil.isNotBlank(params.getOperator())) {
-            request.setAttribute(Constants.DEFAULT_OPERATOR, params.getOperator());
-        }
-
-        final StringBuilder queryBuf = new StringBuilder(255);
-        if (StringUtil.isNotBlank(params.getQuery())) {
-            if (params.getQuery().indexOf(" OR ") >= 0) {
-                queryBuf.append('(').append(params.getQuery()).append(')');
-            } else {
-                queryBuf.append(params.getQuery());
-            }
-        }
-        if (params.getAdditional() != null) {
-            appendAdditionalQuery(params.getAdditional(), additional -> {
-                queryBuf.append(' ').append(additional);
-            });
-        }
-        params.getFields().entrySet().stream().forEach(entry -> {
-            appendQueries(queryBuf, entry.getKey(), entry.getValue());
-        });
-        if (StringUtil.isNotBlank(params.getSort())) {
-            queryBuf.append(" sort:").append(params.getSort());
-        }
-        if (params.getLanguages() != null) {
-            appendQueries(queryBuf, fessConfig.getIndexFieldLang(), params.getLanguages());
-        }
-
-        final String query = queryBuf.toString().trim();
+        final String query =
+                QueryStringBuilder.query(params.getQuery()).extraQueries(params.getExtraQueries()).fields(params.getFields()).build();
 
         final int pageStart = params.getStartPosition();
         final int pageSize = params.getPageSize();
@@ -173,7 +143,7 @@ public class SearchService {
         }
         data.setExecTime(execTime);
 
-        final String queryId = QueryUtil.generateId();
+        final String queryId = queryHelper.generateId();
 
         data.setPageSize(queryResponseList.getPageSize());
         data.setCurrentPageNumber(queryResponseList.getCurrentPageNumber());
@@ -197,32 +167,9 @@ public class SearchService {
     }
 
     public int deleteByQuery(final HttpServletRequest request, final SearchRequestParams params) {
-        if (StringUtil.isNotBlank(params.getOperator())) {
-            request.setAttribute(Constants.DEFAULT_OPERATOR, params.getOperator());
-        }
-
-        final StringBuilder queryBuf = new StringBuilder(255);
-        if (StringUtil.isNotBlank(params.getQuery())) {
-            if (params.getQuery().indexOf(" OR ") >= 0) {
-                queryBuf.append('(').append(params.getQuery()).append(')');
-            } else {
-                queryBuf.append(params.getQuery());
-            }
-        }
-        if (params.getAdditional() != null) {
-            appendAdditionalQuery(params.getAdditional(), additional -> {
-                queryBuf.append(' ').append(additional);
-            });
-        }
-        params.getFields().entrySet().stream().forEach(entry -> {
-            appendQueries(queryBuf, entry.getKey(), entry.getValue());
-        });
-
-        if (params.getLanguages() != null) {
-            appendQueries(queryBuf, fessConfig.getIndexFieldLang(), params.getLanguages());
-        }
 
-        final String query = queryBuf.toString().trim();
+        final String query =
+                QueryStringBuilder.query(params.getQuery()).extraQueries(params.getExtraQueries()).fields(params.getFields()).build();
 
         final QueryContext queryContext = queryHelper.build(query, context -> {
             context.skipRoleQuery();
@@ -324,45 +271,6 @@ public class SearchService {
         return StringUtil.EMPTY_STRINGS;
     }
 
-    protected void appendQueries(final StringBuilder queryBuf, final String key, final String[] values) {
-        if (values.length == 1) {
-            queryBuf.append(' ').append(key).append(":\"").append(values[0]).append('\"');
-        } else if (values.length > 1) {
-            boolean first = true;
-            queryBuf.append(" (");
-            for (final String value : values) {
-                if (first) {
-                    first = false;
-                } else {
-                    queryBuf.append(" OR ");
-                }
-                queryBuf.append(key).append(":\"").append(value).append('\"');
-            }
-            queryBuf.append(')');
-        }
-    }
-
-    public void appendAdditionalQuery(final String[] additionalQueries, final Consumer<String> consumer) {
-        final Set<String> fieldSet = new HashSet<>();
-        for (final String additional : additionalQueries) {
-            if (StringUtil.isNotBlank(additional) && additional.length() < 1000 && !hasFieldInQuery(fieldSet, additional)) {
-                consumer.accept(additional);
-            }
-        }
-    }
-
-    protected boolean hasFieldInQuery(final Set<String> fieldSet, final String query) {
-        final Matcher matcher = FIELD_EXTRACTION_PATTERN.matcher(query);
-        if (matcher.matches()) {
-            final String field = matcher.replaceFirst("$1");
-            if (fieldSet.contains(field)) {
-                return true;
-            }
-            fieldSet.add(field);
-        }
-        return false;
-    }
-
     public OptionalEntity<Map<String, Object>> getDocumentByDocId(final String docId, final String[] fields) {
         return fessEsClient.getDocument(fessConfig.getIndexDocumentIndex(), fessConfig.getIndexDocumentType(), builder -> {
             builder.setQuery(QueryBuilders.termQuery(fessConfig.getIndexFieldDocId(), docId));
@@ -374,7 +282,7 @@ public class SearchService {
     public List<Map<String, Object>> getDocumentListByDocIds(final String[] docIds, final String[] fields) {
         return fessEsClient.getDocumentList(fessConfig.getIndexDocumentIndex(), fessConfig.getIndexDocumentType(), builder -> {
             builder.setQuery(QueryBuilders.termsQuery(fessConfig.getIndexFieldDocId(), docIds));
-            builder.setSize(queryHelper.getMaxPageSize());
+            builder.setSize(fessConfig.getPagingSearchPageMaxSizeAsInteger().intValue());
             builder.addFields(fields);
             return true;
         });

+ 2 - 2
src/main/java/org/codelibs/fess/app/web/admin/searchlist/AdminSearchlistAction.java

@@ -118,9 +118,9 @@ public class AdminSearchlistAction extends FessAdminAction {
     protected HtmlResponse doSearch(final ListForm form) {
         validate(form, messages -> {}, () -> asListHtml());
 
-        if (StringUtil.isBlank(form.query)) {
+        if (StringUtil.isBlank(form.q)) {
             // query matches on all documents.
-            form.query = Constants.MATCHES_ALL_QUERY;
+            form.q = Constants.MATCHES_ALL_QUERY;
         }
         return asListHtml().renderWith(data -> {
             doSearchInternal(data, form);

+ 17 - 26
src/main/java/org/codelibs/fess/app/web/admin/searchlist/ListForm.java

@@ -24,21 +24,20 @@ import javax.validation.constraints.Size;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
 import org.codelibs.fess.entity.SearchRequestParams;
-import org.codelibs.fess.helper.QueryHelper;
+import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
 import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
 
 /**
- * @author codelibs
+ * @author shinsuke
  * @author Keiichi Watanabe
  */
-//public class SearchListForm implements Serializable {
 public class ListForm implements SearchRequestParams, Serializable {
 
     private static final long serialVersionUID = 1L;
 
     @Size(max = 1000)
-    public String query;
+    public String q;
 
     public String sort;
 
@@ -55,24 +54,16 @@ public class ListForm implements SearchRequestParams, Serializable {
 
     @Override
     public String getQuery() {
-        return query;
+        return q;
     }
 
     public Map<String, String[]> fields = new HashMap<>();
 
-    public String additional[];
-
-    @Size(max = 10)
-    public String op;
-
-    @Override
-    public String getOperator() {
-        return op;
-    }
+    public String ex_q[];
 
     @Override
-    public String[] getAdditional() {
-        return additional;
+    public String[] getExtraQueries() {
+        return ex_q;
     }
 
     @Override
@@ -91,19 +82,19 @@ public class ListForm implements SearchRequestParams, Serializable {
     @Override
     public int getStartPosition() {
         if (start == null) {
-            start = ComponentUtil.getQueryHelper().getDefaultStart();
+            start = ComponentUtil.getFessConfig().getPagingSearchPageStartAsInteger();
         }
         return start;
     }
 
     @Override
     public int getPageSize() {
-        final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
         if (num == null) {
-            num = queryHelper.getDefaultPageSize();
+            num = fessConfig.getPagingSearchPageSizeAsInteger();
         }
-        if (num > queryHelper.getMaxPageSize() || num <= 0) {
-            num = queryHelper.getMaxPageSize();
+        if (num > fessConfig.getPagingSearchPageMaxSizeAsInteger().intValue() || num <= 0) {
+            num = fessConfig.getPagingSearchPageMaxSizeAsInteger();
         }
         return num;
     }
@@ -129,14 +120,14 @@ public class ListForm implements SearchRequestParams, Serializable {
     }
 
     public void initialize() {
-        final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
         if (start == null) {
-            start = queryHelper.getDefaultStart();
+            start = fessConfig.getPagingSearchPageStartAsInteger();
         }
         if (num == null) {
-            num = queryHelper.getDefaultPageSize();
-        } else if (num > queryHelper.getMaxPageSize()) {
-            num = queryHelper.getMaxPageSize();
+            num = fessConfig.getPagingSearchPageSizeAsInteger();
+        } else if (num > fessConfig.getPagingSearchPageMaxSizeAsInteger().intValue()) {
+            num = fessConfig.getPagingSearchPageMaxSizeAsInteger();
         }
     }
 

+ 7 - 23
src/main/java/org/codelibs/fess/app/web/search/SearchAction.java

@@ -33,6 +33,7 @@ import org.codelibs.fess.entity.SearchRenderData;
 import org.codelibs.fess.exception.InvalidQueryException;
 import org.codelibs.fess.exception.ResultOffsetExceededException;
 import org.codelibs.fess.util.FacetResponse;
+import org.codelibs.fess.util.StreamUtil;
 import org.lastaflute.taglib.function.LaFunctions;
 import org.lastaflute.web.Execute;
 import org.lastaflute.web.response.HtmlResponse;
@@ -109,21 +110,9 @@ public class SearchAction extends FessSearchAction {
             }
         }
 
-        if (StringUtil.isBlank(form.query)) {
-            try {
-                final String optionQuery = queryHelper.buildOptionQuery(form.options);
-                form.query = optionQuery;
-            } catch (final InvalidQueryException e) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug(e.getMessage(), e);
-                }
-                throwValidationError(e.getMessageCode(), () -> asHtml(path_ErrorJsp));
-            }
-        }
-
-        if (StringUtil.isBlank(form.query) && form.fields.isEmpty()) {
+        if (StringUtil.isBlank(form.q) && form.fields.isEmpty()) {
             // redirect to index page
-            form.query = null;
+            form.q = null;
             return redirect(RootAction.class);
         }
 
@@ -163,7 +152,7 @@ public class SearchAction extends FessSearchAction {
     }
 
     protected HtmlResponse doMove(final SearchForm form, final int move) {
-        int start = queryHelper.getDefaultStart();
+        int start = fessConfig.getPagingSearchPageStartAsInteger();
         if (form.pn != null) {
             int pageNumber = form.pn;
             if (pageNumber > 0) {
@@ -191,7 +180,7 @@ public class SearchAction extends FessSearchAction {
 
     protected String getDisplayQuery(final SearchForm form, final List<Map<String, String>> labelTypeItems) {
         final StringBuilder buf = new StringBuilder(100);
-        buf.append(form.query);
+        buf.append(form.q);
         if (!form.fields.isEmpty() && form.fields.containsKey(LABEL_FIELD)) {
             final String[] values = form.fields.get(LABEL_FIELD);
             final List<String> labelList = new ArrayList<String>();
@@ -215,17 +204,12 @@ public class SearchAction extends FessSearchAction {
 
     protected String getPagingQuery(final SearchForm form) {
         final StringBuilder buf = new StringBuilder(200);
-        if (form.additional != null) {
-            searchService.appendAdditionalQuery(form.additional, additional -> {
-                buf.append("&additional=").append(LaFunctions.u(additional));
-            });
+        if (form.ex_q != null) {
+            StreamUtil.of(form.ex_q).filter(q -> StringUtil.isNotBlank(q)).forEach(q -> buf.append("&ex_q=").append(LaFunctions.u(q)));
         }
         if (StringUtil.isNotBlank(form.sort)) {
             buf.append("&sort=").append(LaFunctions.u(form.sort));
         }
-        if (StringUtil.isNotBlank(form.op)) {
-            buf.append("&op=").append(LaFunctions.u(form.op));
-        }
         if (form.lang != null) {
             final Set<String> langSet = new HashSet<String>();
             for (final String lang : form.lang) {

+ 14 - 23
src/main/java/org/codelibs/fess/app/web/search/SearchForm.java

@@ -24,7 +24,7 @@ import javax.validation.constraints.Size;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
 import org.codelibs.fess.entity.SearchRequestParams;
-import org.codelibs.fess.helper.QueryHelper;
+import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
 import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
 
@@ -35,7 +35,7 @@ public class SearchForm implements SearchRequestParams, Serializable {
     public Map<String, String[]> fields = new HashMap<>();
 
     @Size(max = 1000)
-    public String query;
+    public String q;
 
     @Size(max = 1000)
     public String sort;
@@ -45,10 +45,7 @@ public class SearchForm implements SearchRequestParams, Serializable {
 
     public String[] lang;
 
-    public String additional[];
-
-    @Size(max = 10)
-    public String op;
+    public String ex_q[];
 
     @ValidateTypeFailure
     public Integer start;
@@ -68,29 +65,27 @@ public class SearchForm implements SearchRequestParams, Serializable {
 
     // advance
 
-    public Map<String, String[]> options = new HashMap<>();
-
     @Override
     public int getStartPosition() {
-        final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
         if (start == null) {
-            start = queryHelper.getDefaultStart();
+            start = fessConfig.getPagingSearchPageStartAsInteger();
         }
         return start;
     }
 
     @Override
     public int getPageSize() {
-        final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
         if (num == null) {
-            num = queryHelper.getDefaultPageSize();
+            num = fessConfig.getPagingSearchPageSizeAsInteger();
         } else {
             try {
-                if (num.intValue() > queryHelper.getMaxPageSize() || num.intValue() <= 0) {
-                    num = queryHelper.getMaxPageSize();
+                if (num.intValue() > fessConfig.getPagingSearchPageMaxSizeAsInteger().intValue() || num.intValue() <= 0) {
+                    num = fessConfig.getPagingSearchPageMaxSizeAsInteger();
                 }
             } catch (final NumberFormatException e) {
-                num = queryHelper.getDefaultPageSize();
+                num = fessConfig.getPagingSearchPageSizeAsInteger();
             }
         }
         return num;
@@ -98,17 +93,12 @@ public class SearchForm implements SearchRequestParams, Serializable {
 
     @Override
     public String getQuery() {
-        return query;
-    }
-
-    @Override
-    public String getOperator() {
-        return op;
+        return q;
     }
 
     @Override
-    public String[] getAdditional() {
-        return additional;
+    public String[] getExtraQueries() {
+        return ex_q;
     }
 
     @Override
@@ -140,4 +130,5 @@ public class SearchForm implements SearchRequestParams, Serializable {
     public boolean isAdministrativeAccess() {
         return false;
     }
+
 }

+ 2 - 2
src/main/java/org/codelibs/fess/entity/FacetInfo.java

@@ -41,7 +41,7 @@ public class FacetInfo {
 
     @Override
     public String toString() {
-        return "FacetInfo [field=" + Arrays.toString(field) + ", query=" + Arrays.toString(query) + ", prefix=" + prefix + ", limit="
-                + limit + ", minCount=" + minCount + ", sort=" + sort + ", missing=" + missing + "]";
+        return "FacetInfo [field=" + Arrays.toString(field) + ", q=" + Arrays.toString(query) + ", prefix=" + prefix + ", limit=" + limit
+                + ", minCount=" + minCount + ", sort=" + sort + ", missing=" + missing + "]";
     }
 }

+ 2 - 4
src/main/java/org/codelibs/fess/entity/SearchRequestParams.java

@@ -21,10 +21,6 @@ public interface SearchRequestParams {
 
     String getQuery();
 
-    String getOperator();
-
-    String[] getAdditional();
-
     Map<String, String[]> getFields();
 
     String[] getLanguages();
@@ -41,4 +37,6 @@ public interface SearchRequestParams {
 
     boolean isAdministrativeAccess();
 
+    String[] getExtraQueries();
+
 }

+ 5 - 2
src/main/java/org/codelibs/fess/es/client/FessEsClient.java

@@ -504,7 +504,7 @@ public class FessEsClient implements Client {
 
             if (ComponentUtil.hasQueryHelper()) {
                 final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
-                for (final Map.Entry<String, String[]> entry : queryHelper.getQueryParamMap().entrySet()) {
+                for (final Map.Entry<String, String[]> entry : queryHelper.getQueryRequestHeaderMap().entrySet()) {
                     requestBuilder.putHeader(entry.getKey(), entry.getValue());
                 }
 
@@ -537,7 +537,7 @@ public class FessEsClient implements Client {
                     searchRequestBuilder.setTimeout(TimeValue.timeValueMillis(queryHelper.getTimeAllowed()));
                 }
 
-                for (final Map.Entry<String, String[]> entry : queryHelper.getQueryParamMap().entrySet()) {
+                for (final Map.Entry<String, String[]> entry : queryHelper.getQueryRequestHeaderMap().entrySet()) {
                     searchRequestBuilder.putHeader(entry.getKey(), entry.getValue());
                 }
 
@@ -873,6 +873,9 @@ public class FessEsClient implements Client {
             }
 
             searchRequestBuilder.setQuery(queryContext.getQueryBuilder());
+            if (logger.isDebugEnabled()) {
+                logger.debug("Query: {0}", searchRequestBuilder);
+            }
 
             return true;
         }

+ 68 - 248
src/main/java/org/codelibs/fess/helper/QueryHelper.java

@@ -24,6 +24,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.UUID;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
@@ -77,24 +78,6 @@ public class QueryHelper implements Serializable {
 
     protected static final String INURL_FIELD = "inurl";
 
-    protected static final String AND = "AND";
-
-    protected static final String OR = "OR";
-
-    protected static final String NOT = "NOT";
-
-    protected static final String _OR_ = " OR ";
-
-    protected static final String _AND_ = " AND ";
-
-    protected static final String DEFAULT_OPERATOR = _AND_;
-
-    protected static final int DEFAULT_START_POSITION = 0;
-
-    protected static final int DEFAULT_PAGE_SIZE = 20;
-
-    protected static final int MAX_PAGE_SIZE = 100;
-
     @Resource
     protected DynamicProperties crawlerProperties;
 
@@ -152,35 +135,29 @@ public class QueryHelper implements Serializable {
 
     protected String defaultQueryLanguage;
 
-    protected Map<String, String[]> additionalQueryParamMap = new HashMap<>();
+    protected Map<String, String[]> queryRequestHeaderMap = new HashMap<>();
 
     protected Map<String, String> fieldBoostMap = new HashMap<>();
 
-    protected int defaultPageSize = DEFAULT_PAGE_SIZE;
-
-    protected int defaultStartPosition = DEFAULT_START_POSITION;
-
     @PostConstruct
     public void init() {
         if (responseFields == null) {
-            responseFields =
-                    new String[] { SCORE_FIELD, fessConfig.getIndexFieldId(), fessConfig.getIndexFieldDocId(),
-                            fessConfig.getIndexFieldBoost(), fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldHost(),
-                            fessConfig.getIndexFieldSite(), fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
-                            fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldCreated(),
-                            fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldDigest(), fessConfig.getIndexFieldUrl(),
-                            fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount(),
-                            fessConfig.getIndexFieldConfigId(), fessConfig.getIndexFieldLang(), fessConfig.getIndexFieldHasCache() };
+            responseFields = new String[] { SCORE_FIELD, fessConfig.getIndexFieldId(), fessConfig.getIndexFieldDocId(),
+                    fessConfig.getIndexFieldBoost(), fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldHost(),
+                    fessConfig.getIndexFieldSite(), fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
+                    fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldCreated(),
+                    fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldDigest(), fessConfig.getIndexFieldUrl(),
+                    fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount(), fessConfig.getIndexFieldConfigId(),
+                    fessConfig.getIndexFieldLang(), fessConfig.getIndexFieldHasCache() };
         }
         if (cacheResponseFields == null) {
-            cacheResponseFields =
-                    new String[] { SCORE_FIELD, fessConfig.getIndexFieldId(), fessConfig.getIndexFieldDocId(),
-                            fessConfig.getIndexFieldBoost(), fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldHost(),
-                            fessConfig.getIndexFieldSite(), fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
-                            fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldCreated(),
-                            fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldDigest(), fessConfig.getIndexFieldUrl(),
-                            fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount(),
-                            fessConfig.getIndexFieldConfigId(), fessConfig.getIndexFieldLang(), fessConfig.getIndexFieldCache() };
+            cacheResponseFields = new String[] { SCORE_FIELD, fessConfig.getIndexFieldId(), fessConfig.getIndexFieldDocId(),
+                    fessConfig.getIndexFieldBoost(), fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldHost(),
+                    fessConfig.getIndexFieldSite(), fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
+                    fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldCreated(),
+                    fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldDigest(), fessConfig.getIndexFieldUrl(),
+                    fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount(), fessConfig.getIndexFieldConfigId(),
+                    fessConfig.getIndexFieldLang(), fessConfig.getIndexFieldCache() };
         }
         if (responseDocValuesFields == null) {
             responseDocValuesFields = new String[] { fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount() };
@@ -189,35 +166,31 @@ public class QueryHelper implements Serializable {
             highlightedFields = new String[] { fessConfig.getIndexFieldContent() };
         }
         if (searchFields == null) {
-            searchFields =
-                    new String[] { INURL_FIELD, fessConfig.getIndexFieldUrl(), fessConfig.getIndexFieldDocId(),
-                            fessConfig.getIndexFieldHost(), fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldContent(),
-                            fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldLastModified(),
-                            fessConfig.getIndexFieldTimestamp(), fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(),
-                            fessConfig.getIndexFieldLabel(), fessConfig.getIndexFieldSegment(), fessConfig.getIndexFieldClickCount(),
-                            fessConfig.getIndexFieldFavoriteCount(), fessConfig.getIndexFieldLang() };
+            searchFields = new String[] { INURL_FIELD, fessConfig.getIndexFieldUrl(), fessConfig.getIndexFieldDocId(),
+                    fessConfig.getIndexFieldHost(), fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldContent(),
+                    fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
+                    fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldLabel(),
+                    fessConfig.getIndexFieldSegment(), fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount(),
+                    fessConfig.getIndexFieldLang() };
         }
         if (facetFields == null) {
-            facetFields =
-                    new String[] { fessConfig.getIndexFieldUrl(), fessConfig.getIndexFieldHost(), fessConfig.getIndexFieldTitle(),
-                            fessConfig.getIndexFieldContent(), fessConfig.getIndexFieldContentLength(),
-                            fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
-                            fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldLabel(),
-                            fessConfig.getIndexFieldSegment() };
+            facetFields = new String[] { fessConfig.getIndexFieldUrl(), fessConfig.getIndexFieldHost(), fessConfig.getIndexFieldTitle(),
+                    fessConfig.getIndexFieldContent(), fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldLastModified(),
+                    fessConfig.getIndexFieldTimestamp(), fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(),
+                    fessConfig.getIndexFieldLabel(), fessConfig.getIndexFieldSegment() };
         }
         if (supportedSortFields == null) {
-            supportedSortFields =
-                    new String[] { fessConfig.getIndexFieldCreated(), fessConfig.getIndexFieldContentLength(),
-                            fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
-                            fessConfig.getIndexFieldClickCount(), fessConfig.getIndexFieldFavoriteCount() };
+            supportedSortFields = new String[] { fessConfig.getIndexFieldCreated(), fessConfig.getIndexFieldContentLength(),
+                    fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(), fessConfig.getIndexFieldClickCount(),
+                    fessConfig.getIndexFieldFavoriteCount() };
         }
         if (apiResponseFieldSet == null) {
-            setApiResponseFields(new String[] { "urlLink", "contentDescription", fessConfig.getIndexFieldId(),
-                    fessConfig.getIndexFieldDocId(), fessConfig.getIndexFieldBoost(), fessConfig.getIndexFieldContentLength(),
-                    fessConfig.getIndexFieldHost(), fessConfig.getIndexFieldSite(), fessConfig.getIndexFieldLastModified(),
-                    fessConfig.getIndexFieldTimestamp(), fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(),
-                    fessConfig.getIndexFieldCreated(), fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldDigest(),
-                    fessConfig.getIndexFieldUrl() });
+            setApiResponseFields(
+                    new String[] { "urlLink", "contentDescription", fessConfig.getIndexFieldId(), fessConfig.getIndexFieldDocId(),
+                            fessConfig.getIndexFieldBoost(), fessConfig.getIndexFieldContentLength(), fessConfig.getIndexFieldHost(),
+                            fessConfig.getIndexFieldSite(), fessConfig.getIndexFieldLastModified(), fessConfig.getIndexFieldTimestamp(),
+                            fessConfig.getIndexFieldMimetype(), fessConfig.getIndexFieldFiletype(), fessConfig.getIndexFieldCreated(),
+                            fessConfig.getIndexFieldTitle(), fessConfig.getIndexFieldDigest(), fessConfig.getIndexFieldUrl() });
         }
     }
 
@@ -274,6 +247,7 @@ public class QueryHelper implements Serializable {
             } else {
                 queryContext.setQueryBuilder(QueryBuilders.matchAllQuery());
             }
+            // TODO options query
             context.accept(queryContext);
         } catch (final ParseException e) {
             throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryParseError(ActionMessages.GLOBAL_PROPERTY_KEY),
@@ -303,7 +277,7 @@ public class QueryHelper implements Serializable {
             return QueryBuilders.matchAllQuery();
         }
         throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryUnknown(ActionMessages.GLOBAL_PROPERTY_KEY),
-                "Unknown query: " + query.getClass() + " => " + query);
+                "Unknown q: " + query.getClass() + " => " + query);
     }
 
     protected QueryBuilder convertBooleanQuery(final QueryContext context, final BooleanQuery booleanQuery) {
@@ -367,8 +341,8 @@ public class QueryHelper implements Serializable {
         // TODO fuzzy value
         if (Constants.DEFAULT_FIELD.equals(field)) {
             context.addFieldLog(field, term.text());
-            return buildDefaultQueryBuilder((f, b) -> QueryBuilders.fuzzyQuery(f, term.text())
-                    .fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())).boost(b));
+            return buildDefaultQueryBuilder(
+                    (f, b) -> QueryBuilders.fuzzyQuery(f, term.text()).fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())).boost(b));
         } else if (isSearchField(field)) {
             context.addFieldLog(field, term.text());
             return QueryBuilders.fuzzyQuery(field, term.text()).boost(fuzzyQuery.getBoost())
@@ -377,8 +351,8 @@ public class QueryHelper implements Serializable {
             final String origQuery = fuzzyQuery.toString();
             context.addFieldLog(Constants.DEFAULT_FIELD, origQuery);
             context.addHighlightedQuery(origQuery);
-            return buildDefaultQueryBuilder((f, b) -> QueryBuilders.fuzzyQuery(f, origQuery)
-                    .fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())).boost(b));
+            return buildDefaultQueryBuilder(
+                    (f, b) -> QueryBuilders.fuzzyQuery(f, origQuery).fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())).boost(b));
         }
     }
 
@@ -423,20 +397,23 @@ public class QueryHelper implements Serializable {
         } else if ("sort".equals(field)) {
             final String[] values = text.split("\\.");
             if (values.length > 2) {
-                throw new InvalidQueryException(messages -> messages.addErrorsInvalidQuerySortValue(ActionMessages.GLOBAL_PROPERTY_KEY,
-                        text), "Invalid sort field: " + termQuery);
+                throw new InvalidQueryException(
+                        messages -> messages.addErrorsInvalidQuerySortValue(ActionMessages.GLOBAL_PROPERTY_KEY, text),
+                        "Invalid sort field: " + termQuery);
             }
             final String sortField = values[0];
             if (!isSortField(sortField)) {
-                throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryUnsupportedSortField(
-                        ActionMessages.GLOBAL_PROPERTY_KEY, sortField), "Unsupported sort field: " + termQuery);
+                throw new InvalidQueryException(
+                        messages -> messages.addErrorsInvalidQueryUnsupportedSortField(ActionMessages.GLOBAL_PROPERTY_KEY, sortField),
+                        "Unsupported sort field: " + termQuery);
             }
             SortOrder sortOrder;
             if (values.length == 2) {
                 sortOrder = SortOrder.valueOf(values[1]);
                 if (sortOrder == null) {
-                    throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryUnsupportedSortOrder(
-                            ActionMessages.GLOBAL_PROPERTY_KEY, values[1]), "Invalid sort order: " + termQuery);
+                    throw new InvalidQueryException(
+                            messages -> messages.addErrorsInvalidQueryUnsupportedSortOrder(ActionMessages.GLOBAL_PROPERTY_KEY, values[1]),
+                            "Invalid sort order: " + termQuery);
                 }
             } else {
                 sortOrder = SortOrder.ASC;
@@ -474,17 +451,14 @@ public class QueryHelper implements Serializable {
         final QueryBuilder contentQuery =
                 builder.apply(fessConfig.getIndexFieldContent(), fessConfig.getQueryBoostContentAsDecimal().floatValue());
         boolQuery.should(contentQuery);
-        getQueryLanguage().ifPresent(
-                lang -> {
-                    final QueryBuilder titleLangQuery =
-                            builder.apply(fessConfig.getIndexFieldTitle() + "_" + lang, fessConfig.getQueryBoostTitleLangAsDecimal()
-                                    .floatValue());
-                    boolQuery.should(titleLangQuery);
-                    final QueryBuilder contentLangQuery =
-                            builder.apply(fessConfig.getIndexFieldContent() + "_" + lang, fessConfig.getQueryBoostContentLangAsDecimal()
-                                    .floatValue());
-                    boolQuery.should(contentLangQuery);
-                });
+        getQueryLanguage().ifPresent(lang -> {
+            final QueryBuilder titleLangQuery =
+                    builder.apply(fessConfig.getIndexFieldTitle() + "_" + lang, fessConfig.getQueryBoostTitleLangAsDecimal().floatValue());
+            boolQuery.should(titleLangQuery);
+            final QueryBuilder contentLangQuery = builder.apply(fessConfig.getIndexFieldContent() + "_" + lang,
+                    fessConfig.getQueryBoostContentLangAsDecimal().floatValue());
+            boolQuery.should(contentLangQuery);
+        });
         return boolQuery;
     }
 
@@ -519,110 +493,6 @@ public class QueryHelper implements Serializable {
 
     }
 
-    public String buildOptionQuery(final Map<String, String[]> optionMap) {
-        if (optionMap == null) {
-            return StringUtil.EMPTY;
-        }
-
-        // TODO
-        final StringBuilder buf = new StringBuilder();
-
-        //        final String[] qs = optionMap.get(Constants.OPTION_QUERY_Q);
-        //        if (qs != null) {
-        //            for (final String q : qs) {
-        //                if (StringUtil.isNotBlank(q)) {
-        //                    buf.append(' ');
-        //                    buf.append(q);
-        //                }
-        //            }
-        //        }
-        //
-        //        final String[] cqs = optionMap.get(Constants.OPTION_QUERY_CQ);
-        //        if (cqs != null) {
-        //            for (final String cq : cqs) {
-        //                if (StringUtil.isNotBlank(cq)) {
-        //                    buf.append(' ');
-        //                    char split = 0;
-        //                    final List<QueryPart> partList = splitQuery(cq.indexOf('"') >= 0 ? cq : "\"" + cq + "\"", null, null, null);
-        //                    for (final QueryPart part : partList) {
-        //                        if (split == 0) {
-        //                            split = ' ';
-        //                        } else {
-        //                            buf.append(split);
-        //                        }
-        //                        final String value = part.getValue();
-        //                        buf.append('"');
-        //                        buf.append(value);
-        //                        buf.append('"');
-        //                    }
-        //                }
-        //            }
-        //        }
-        //
-        //        final String[] oqs = optionMap.get(Constants.OPTION_QUERY_OQ);
-        //        if (oqs != null) {
-        //            for (final String oq : oqs) {
-        //                if (StringUtil.isNotBlank(oq)) {
-        //                    buf.append(' ');
-        //                    final List<QueryPart> partList = splitQuery(oq, null, null, null);
-        //                    final boolean append = partList.size() > 1 && optionMap.size() > 1;
-        //                    if (append) {
-        //                        buf.append('(');
-        //                    }
-        //                    String split = null;
-        //                    for (final QueryPart part : partList) {
-        //                        if (split == null) {
-        //                            split = _OR_;
-        //                        } else {
-        //                            buf.append(split);
-        //                        }
-        //                        final String value = part.getValue();
-        //                        final boolean hasSpace = value.matches(".*\\s.*");
-        //                        if (hasSpace) {
-        //                            buf.append('"');
-        //                        }
-        //                        buf.append(value);
-        //                        if (hasSpace) {
-        //                            buf.append('"');
-        //                        }
-        //                    }
-        //                    if (append) {
-        //                        buf.append(')');
-        //                    }
-        //                }
-        //            }
-        //        }
-        //
-        //        final String[] nqs = optionMap.get(Constants.OPTION_QUERY_NQ);
-        //        if (nqs != null) {
-        //            for (final String nq : nqs) {
-        //                if (StringUtil.isNotBlank(nq)) {
-        //                    buf.append(' ');
-        //                    String split = StringUtil.EMPTY;
-        //                    final List<QueryPart> partList = splitQuery(nq, null, null, null);
-        //                    for (final QueryPart part : partList) {
-        //                        buf.append(split);
-        //                        if (split.length() == 0) {
-        //                            split = " ";
-        //                        }
-        //                        buf.append(NOT_);
-        //                        final String value = part.getValue();
-        //                        final boolean hasSpace = value.matches(".*\\s.*");
-        //                        if (hasSpace) {
-        //                            buf.append('"');
-        //                        }
-        //                        buf.append(value);
-        //                        if (hasSpace) {
-        //                            buf.append('"');
-        //                        }
-        //                    }
-        //                }
-        //            }
-        //        }
-
-        return buf.toString().trim();
-    }
-
     private boolean isSortField(final String field) {
         for (final String f : supportedSortFields) {
             if (f.equals(field)) {
@@ -841,7 +711,8 @@ public class QueryHelper implements Serializable {
         if (defaultSortBuilders != null) {
             StreamUtil.of(defaultSortBuilders).forEach(builder -> list.add(builder));
         }
-        list.add(SortBuilders.fieldSort(fieldName).order(SortOrder.ASC.toString().equalsIgnoreCase(order) ? SortOrder.ASC : SortOrder.DESC));
+        list.add(
+                SortBuilders.fieldSort(fieldName).order(SortOrder.ASC.toString().equalsIgnoreCase(order) ? SortOrder.ASC : SortOrder.DESC));
         defaultSortBuilders = list.toArray(new SortBuilder[list.size()]);
     }
 
@@ -877,42 +748,14 @@ public class QueryHelper implements Serializable {
         this.defaultQueryLanguage = defaultQueryLanguage;
     }
 
-    public int getMaxPageSize() {
-        final Object maxPageSize = crawlerProperties.get(Constants.SEARCH_RESULT_MAX_PAGE_SIZE);
-        if (maxPageSize == null) {
-            return MAX_PAGE_SIZE;
-        }
-        try {
-            return Integer.parseInt(maxPageSize.toString());
-        } catch (final NumberFormatException e) {
-            return MAX_PAGE_SIZE;
-        }
-    }
-
-    public int getDefaultPageSize() {
-        return defaultPageSize;
-    }
-
-    public void setDefaultPageSize(final int defaultPageSize) {
-        this.defaultPageSize = defaultPageSize;
-    }
-
-    public int getDefaultStart() {
-        return defaultStartPosition;
-    }
-
-    public void setDefaultStart(final int defaultStartPosition) {
-        this.defaultStartPosition = defaultStartPosition;
-    }
-
-    public Map<String, String[]> getQueryParamMap() {
-        if (additionalQueryParamMap.isEmpty()) {
-            return additionalQueryParamMap;
+    public Map<String, String[]> getQueryRequestHeaderMap() {
+        if (queryRequestHeaderMap.isEmpty()) {
+            return queryRequestHeaderMap;
         }
 
         final HttpServletRequest request = LaRequestUtil.getOptionalRequest().orElse(null);
         final Map<String, String[]> queryParamMap = new HashMap<String, String[]>();
-        for (final Map.Entry<String, String[]> entry : additionalQueryParamMap.entrySet()) {
+        for (final Map.Entry<String, String[]> entry : queryRequestHeaderMap.entrySet()) {
             final String[] values = entry.getValue();
             final String[] newValues = new String[values.length];
             for (int i = 0; i < values.length; i++) {
@@ -934,35 +777,12 @@ public class QueryHelper implements Serializable {
         return queryParamMap;
     }
 
-    public void addQueryParam(final String key, final String[] values) {
-        additionalQueryParamMap.put(key, values);
-    }
-
-    public void addFieldBoost(final String field, final String value) {
-        try {
-            Float.parseFloat(value);
-        } catch (final NumberFormatException e) {
-            throw new IllegalArgumentException(value + " was not number.", e);
-        }
-        fieldBoostMap.put(field, value);
+    public void addQueryRequestHeader(final String key, final String[] values) {
+        queryRequestHeaderMap.put(key, values);
     }
 
-    protected String getDefaultOperator() {
-        final HttpServletRequest request = LaRequestUtil.getOptionalRequest().orElse(null);
-        if (request != null) {
-            final String defaultOperator = (String) request.getAttribute(Constants.DEFAULT_OPERATOR);
-            if (AND.equalsIgnoreCase(defaultOperator)) {
-                return _AND_;
-            } else if (OR.equalsIgnoreCase(defaultOperator)) {
-                return _OR_;
-            }
-        }
-        return DEFAULT_OPERATOR;
+    public String generateId() {
+        return UUID.randomUUID().toString().replace("-", StringUtil.EMPTY);
     }
 
-    protected void appendFieldBoostValue(final StringBuilder buf, final String field, final String value) {
-        if (fieldBoostMap.containsKey(field) && value.indexOf('^') == -1 && value.indexOf('~') == -1) {
-            buf.append('^').append(fieldBoostMap.get(field));
-        }
-    }
 }

+ 108 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -115,6 +115,9 @@ public interface FessConfig extends FessEnv {
     /** The key of the configuration. e.g. doc */
     String INDEX_DOCUMENT_TYPE = "index.document.type";
 
+    /** The key of the configuration. e.g. 1000 */
+    String QUERY_MAX_LENGTH = "query.max.length";
+
     /** The key of the configuration. e.g. 1.6 */
     String QUERY_BOOST_TITLE = "query.boost.title";
 
@@ -166,6 +169,15 @@ public interface FessConfig extends FessEnv {
     /** The key of the configuration. e.g. 1000 */
     String PAGE_GROUP_MAX_FETCH_SIZE = "page.group.max.fetch.size";
 
+    /** The key of the configuration. e.g. 0 */
+    String PAGING_SEARCH_PAGE_START = "paging.search.page.start";
+
+    /** The key of the configuration. e.g. 20 */
+    String PAGING_SEARCH_PAGE_SIZE = "paging.search.page.size";
+
+    /** The key of the configuration. e.g. 100 */
+    String PAGING_SEARCH_PAGE_MAX_SIZE = "paging.search.page.max.size";
+
     /** The key of the configuration. e.g. Administrator */
     String MAIL_FROM_NAME = "mail.from.name";
 
@@ -511,6 +523,23 @@ public interface FessConfig extends FessEnv {
      */
     String getIndexDocumentType();
 
+    /**
+     * Get the value for the key 'query.max.length'. <br>
+     * The value is, e.g. 1000 <br>
+     * comment: query
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getQueryMaxLength();
+
+    /**
+     * Get the value for the key 'query.max.length' as {@link Integer}. <br>
+     * The value is, e.g. 1000 <br>
+     * comment: query
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     * @throws NumberFormatException When the property is not integer.
+     */
+    Integer getQueryMaxLengthAsInteger();
+
     /**
      * Get the value for the key 'query.boost.title'. <br>
      * The value is, e.g. 1.6 <br>
@@ -750,6 +779,53 @@ public interface FessConfig extends FessEnv {
      */
     Integer getPageGroupMaxFetchSizeAsInteger();
 
+    /**
+     * Get the value for the key 'paging.search.page.start'. <br>
+     * The value is, e.g. 0 <br>
+     * comment: search page
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getPagingSearchPageStart();
+
+    /**
+     * Get the value for the key 'paging.search.page.start' as {@link Integer}. <br>
+     * The value is, e.g. 0 <br>
+     * comment: search page
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     * @throws NumberFormatException When the property is not integer.
+     */
+    Integer getPagingSearchPageStartAsInteger();
+
+    /**
+     * Get the value for the key 'paging.search.page.size'. <br>
+     * The value is, e.g. 20 <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getPagingSearchPageSize();
+
+    /**
+     * Get the value for the key 'paging.search.page.size' as {@link Integer}. <br>
+     * The value is, e.g. 20 <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     * @throws NumberFormatException When the property is not integer.
+     */
+    Integer getPagingSearchPageSizeAsInteger();
+
+    /**
+     * Get the value for the key 'paging.search.page.max.size'. <br>
+     * The value is, e.g. 100 <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     */
+    String getPagingSearchPageMaxSize();
+
+    /**
+     * Get the value for the key 'paging.search.page.max.size' as {@link Integer}. <br>
+     * The value is, e.g. 100 <br>
+     * @return The value of found property. (NotNull: if not found, exception but basically no way)
+     * @throws NumberFormatException When the property is not integer.
+     */
+    Integer getPagingSearchPageMaxSizeAsInteger();
+
     /**
      * Get the value for the key 'mail.from.name'. <br>
      * The value is, e.g. Administrator <br>
@@ -1127,6 +1203,14 @@ public interface FessConfig extends FessEnv {
             return get(FessConfig.INDEX_DOCUMENT_TYPE);
         }
 
+        public String getQueryMaxLength() {
+            return get(FessConfig.QUERY_MAX_LENGTH);
+        }
+
+        public Integer getQueryMaxLengthAsInteger() {
+            return getAsInteger(FessConfig.QUERY_MAX_LENGTH);
+        }
+
         public String getQueryBoostTitle() {
             return get(FessConfig.QUERY_BOOST_TITLE);
         }
@@ -1247,6 +1331,30 @@ public interface FessConfig extends FessEnv {
             return getAsInteger(FessConfig.PAGE_GROUP_MAX_FETCH_SIZE);
         }
 
+        public String getPagingSearchPageStart() {
+            return get(FessConfig.PAGING_SEARCH_PAGE_START);
+        }
+
+        public Integer getPagingSearchPageStartAsInteger() {
+            return getAsInteger(FessConfig.PAGING_SEARCH_PAGE_START);
+        }
+
+        public String getPagingSearchPageSize() {
+            return get(FessConfig.PAGING_SEARCH_PAGE_SIZE);
+        }
+
+        public Integer getPagingSearchPageSizeAsInteger() {
+            return getAsInteger(FessConfig.PAGING_SEARCH_PAGE_SIZE);
+        }
+
+        public String getPagingSearchPageMaxSize() {
+            return get(FessConfig.PAGING_SEARCH_PAGE_MAX_SIZE);
+        }
+
+        public Integer getPagingSearchPageMaxSizeAsInteger() {
+            return getAsInteger(FessConfig.PAGING_SEARCH_PAGE_MAX_SIZE);
+        }
+
         public String getMailFromName() {
             return get(FessConfig.MAIL_FROM_NAME);
         }

+ 0 - 26
src/main/java/org/codelibs/fess/util/MoreLikeThisResponse.java

@@ -1,26 +0,0 @@
-/*
- * Copyright 2012-2015 CodeLibs Project and the Others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-package org.codelibs.fess.util;
-
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class MoreLikeThisResponse extends LinkedHashMap<String, List<Map<String, Object>>> {
-
-    private static final long serialVersionUID = 1L;
-
-}

+ 78 - 0
src/main/java/org/codelibs/fess/util/QueryStringBuilder.java

@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012-2015 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.util;
+
+import java.util.Map;
+
+import org.codelibs.core.lang.StringUtil;
+import org.codelibs.fess.mylasta.direction.FessConfig;
+
+public class QueryStringBuilder {
+    private String query;
+
+    private String[] extraQueries;
+
+    private Map<String, String[]> fieldMap;
+
+    public String build() {
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        final StringBuilder queryBuf = new StringBuilder(255);
+        if (StringUtil.isNotBlank(query)) {
+            queryBuf.append('(').append(query).append(')');
+        }
+        StreamUtil.of(extraQueries)
+                .filter(q -> StringUtil.isNotBlank(q) && q.length() <= fessConfig.getQueryMaxLengthAsInteger().intValue())
+                .forEach(q -> queryBuf.append(' ').append(q));
+        StreamUtil.of(fieldMap).forEach(entry -> {
+            final String key = entry.getKey();
+            final String[] values = entry.getValue();
+            if (values == null) {
+                // nothing
+            } else if (values.length == 1) {
+                queryBuf.append(' ').append(key).append(":\"").append(values[0]).append('\"');
+            } else if (values.length > 1) {
+                boolean first = true;
+                queryBuf.append(" (");
+                for (final String value : values) {
+                    if (first) {
+                        first = false;
+                    } else {
+                        queryBuf.append(" OR ");
+                    }
+                    queryBuf.append(key).append(":\"").append(value).append('\"');
+                }
+                queryBuf.append(')');
+            }
+        });
+        return queryBuf.toString();
+    }
+
+    public static QueryStringBuilder query(String query) {
+        QueryStringBuilder builder = new QueryStringBuilder();
+        builder.query = query;
+        return builder;
+    }
+
+    public QueryStringBuilder extraQueries(String[] extraQueries) {
+        this.extraQueries = extraQueries;
+        return this;
+    }
+
+    public QueryStringBuilder fields(Map<String, String[]> fieldMap) {
+        this.fieldMap = fieldMap;
+        return this;
+    }
+}

+ 0 - 53
src/main/java/org/codelibs/fess/util/QueryUtil.java

@@ -1,53 +0,0 @@
-/*
- * Copyright 2012-2015 CodeLibs Project and the Others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-package org.codelibs.fess.util;
-
-import java.util.UUID;
-
-import org.codelibs.core.lang.StringUtil;
-import org.codelibs.fess.Constants;
-
-public class QueryUtil {
-    protected QueryUtil() {
-        // nothing
-    }
-
-    public static String escapeValue(final String value) {
-        final String escapedValue = Constants.LUCENE_FIELD_RESERVED_PATTERN.matcher(value).replaceAll("\\\\$1");
-        if (escapedValue.length() > 1) {
-            final char c = escapedValue.charAt(0);
-            if (c == '*' || c == '?') {
-                return "\\" + escapedValue;
-            }
-        }
-        return escapedValue;
-    }
-
-    public static String escapeRangeValue(final String value) {
-        final String escapedValue = Constants.LUCENE_RANGE_FIELD_RESERVED_PATTERN.matcher(value).replaceAll("\\\\$1");
-        if (escapedValue.length() > 1) {
-            final char c = escapedValue.charAt(0);
-            if (c == '*' || c == '?') {
-                return "\\" + escapedValue;
-            }
-        }
-        return escapedValue;
-    }
-
-    public static String generateId() {
-        return UUID.randomUUID().toString().replace("-", StringUtil.EMPTY);
-    }
-}

+ 11 - 0
src/main/java/org/codelibs/fess/util/StreamUtil.java

@@ -17,9 +17,11 @@ package org.codelibs.fess.util;
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Map;
 import java.util.stream.Stream;
 
 public class StreamUtil {
+    @SafeVarargs
     public static <T> Stream<T> of(final T... values) {
         if (values != null) {
             return Arrays.stream(values);
@@ -27,4 +29,13 @@ public class StreamUtil {
             return Collections.<T> emptyList().stream();
         }
     }
+
+    public static <K, V> Stream<Map.Entry<K, V>> of(final Map<K, V> map) {
+        if (map != null) {
+            return map.entrySet().stream();
+        } else {
+            return Collections.<K, V> emptyMap().entrySet().stream();
+        }
+    }
+
 }

+ 0 - 4
src/main/resources/app.xml

@@ -69,10 +69,6 @@
 		<postConstruct name="addHighlightField">
 			<arg>"content"</arg>
 		</postConstruct>
-		<postConstruct name="addFieldBoost">
-			<arg>"label"</arg>
-			<arg>"0.0"</arg>
-		</postConstruct>
 	</component>
 	<component name="viewHelper" class="org.codelibs.fess.helper.ViewHelper">
 		<postConstruct name="addFacetQueryView">

+ 8 - 0
src/main/resources/fess_config.properties

@@ -48,6 +48,9 @@ index.field.filetype=filetype
 index.document.index=fess
 index.document.type=doc
 
+# query
+query.max.length=1000
+
 # boost
 query.boost.title=1.6
 query.boost.title.lang=2.0
@@ -97,6 +100,11 @@ page.keymatch.max.fetch.size=1000
 page.role.max.fetch.size=1000
 page.group.max.fetch.size=1000
 
+# search page
+paging.search.page.start=0
+paging.search.page.size=20
+paging.search.page.max.size=100
+
 # ----------------------------------------------------------
 #                                                      Mail
 #                                                     ------

+ 1 - 1
src/main/webapp/WEB-INF/view/admin/crawlinginfo/admin_crawlinginfo_details.jsp

@@ -76,7 +76,7 @@
 												<th><la:message
 														key="labels.crawling_info_session_id" /></th>
 												<td><a
-													href="${f:url('/admin/searchlist/search')}?query=segment:${f:u(sessionId)}">${f:h(sessionId)}</a>
+													href="${f:url('/admin/searchlist/search')}?q=segment:${f:u(sessionId)}">${f:h(sessionId)}</a>
 													<la:hidden property="sessionId" /></td>
 											</tr>
 											<c:forEach var="info" items="${crawlingInfoParamItems}">

+ 7 - 7
src/main/webapp/WEB-INF/view/admin/searchlist/admin_searchlist.jsp

@@ -46,7 +46,7 @@
 								<la:form action="/admin/searchlist" styleClass="form-inline">
 									<div class="form-group">
 										<label class="sr-only" for="sessionIdSearchBtn"></label>
-										<la:text styleClass="query form-control" property="query"
+										<la:text styleClass="query form-control" property="q"
 											title="Search" size="50" maxlength="1000"
 											placeholder="Type a search query" />
 									</div>
@@ -66,7 +66,7 @@
 										<div id="subheader" class="row top10">
 											<div class="col-xs-12">
 												<la:message key="labels.search_result_status"
-													arg0="${f:h(query)}" arg1="${f:h(allRecordCount)}"
+													arg0="${f:h(q)}" arg1="${f:h(allRecordCount)}"
 													arg2="${f:h(currentStartRecordNumber)}"
 													arg3="${f:h(currentEndRecordNumber)}" />
 												<c:if test="${execTime!=null}">
@@ -103,7 +103,7 @@
 												<ul class="pagination pagination-sm">
 													<c:if test="${existPrePage}">
 														<li class="prev"><la:link
-																href="prev?query=${f:u(query)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}&labelTypeValue=${f:u(labelTypeValue)}">
+																href="prev?q=${f:u(q)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}&labelTypeValue=${f:u(labelTypeValue)}">
 																<la:message key="labels.prev_page" />
 															</la:link></li>
 													</c:if>
@@ -116,14 +116,14 @@
 														<li
 															<c:if test="${pageNumber == currentPageNumber}">class="active"</c:if>>
 															<la:link
-																href="move?query=${f:u(query)}&pn=${f:u(pageNumber)}&num=${f:u(pageSize)}&labelTypeValue=${f:u(labelTypeValue)}">${f:h(pageNumber)}</la:link>
+																href="move?q=${f:u(q)}&pn=${f:u(pageNumber)}&num=${f:u(pageSize)}&labelTypeValue=${f:u(labelTypeValue)}">${f:h(pageNumber)}</la:link>
 														</li>
 													</c:forEach>
 													<c:if test="${existNextPage}">
 														<li
 															class="next<c:if test="${!existNextPage}"> disabled</c:if>">
 															<la:link
-																href="next?query=${f:u(query)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}&labelTypeValue=${f:u(labelTypeValue)}">
+																href="next?q=${f:u(q)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}&labelTypeValue=${f:u(labelTypeValue)}">
 																<la:message key="labels.next_page" />
 															</la:link>
 														</li>
@@ -140,7 +140,7 @@
 										<div id="result" class="row top10">
 											<div class="col-sm-12">
 												<p class="callout callout-info">
-													<la:message key="labels.did_not_match" arg0="${f:h(query)}" />
+													<la:message key="labels.did_not_match" arg0="${f:h(q)}" />
 												</p>
 											</div>
 										</div>
@@ -219,7 +219,7 @@
 													</div>
 													<div class="modal-footer">
 														<la:form action="/admin/searchlist/deleteall">
-															<la:hidden property="query" />
+															<la:hidden property="q" />
 															<button type="button" class="btn btn-outline pull-left"
 																data-dismiss="modal">
 																<la:message key="labels.search_list_button_cancel" />

+ 1 - 1
src/main/webapp/WEB-INF/view/common/admin/sidebar.jsp

@@ -9,7 +9,7 @@
 		<form action="<%=request.getContextPath()%>/admin/searchlist/search" method="post"
 			class="sidebar-form">
 			<div class="input-group">
-				<input type="text" name="query" id="query" class="form-control"
+				<input type="text" name="q" id="query" class="form-control"
 					maxlength="1000"
 					placeholder="<la:message key="labels.sidebar.placeholder_search" />">
 				<span class="input-group-btn">

+ 1 - 1
src/main/webapp/WEB-INF/view/error/header.jsp

@@ -8,7 +8,7 @@ ${fe:facetForm()}${fe:geoForm()}
 				alt="<la:message key="labels.header_brand_name" />" />
 		</la:link>
 		<div class="form-inline navbar-form pull-right">
-			<la:text property="query" maxlength="1000" styleId="query"
+			<la:text property="q" maxlength="1000" styleId="query"
 				styleClass="form-control" autocomplete="off" />
 			<button class="btn medium btn-primary" type="submit" name="search"
 				id="searchButton">

+ 1 - 1
src/main/webapp/WEB-INF/view/header.jsp

@@ -27,7 +27,7 @@ ${fe:facetForm()}${fe:geoForm()}
 			class="search-box navbar-form col-lg-5 col-md-6 col-sm-6 col-xs-8 pull-right"
 			role="search">
 			<div class="input-group">
-				<la:text property="query" maxlength="1000" styleId="query"
+				<la:text property="q" maxlength="1000" styleId="query"
 					styleClass="form-control" autocomplete="off" />
 				<span class="input-group-btn">
 					<button type="submit" name="search" id="searchButton"

+ 2 - 2
src/main/webapp/WEB-INF/view/index.jsp

@@ -66,7 +66,7 @@
 						<div class="clearfix">
 							<div class="input">
 								<la:text styleClass="query form-control center-block"
-									property="query" size="50" maxlength="1000"
+									property="q" size="50" maxlength="1000"
 									styleId="contentQuery" autocomplete="off" />
 							</div>
 						</div>
@@ -76,7 +76,7 @@
 									<la:message key="labels.search_hot_search_word" />
 									<c:forEach var="item" items="${fe:hsw(null, 5)}">
 										<la:link
-											href="/search/search?query=${f:u(item)}${fe:facetQuery()}${fe:geoQuery()}">${f:h(item)}</la:link>
+											href="/search/search?q=${f:u(item)}${fe:facetQuery()}${fe:geoQuery()}">${f:h(item)}</la:link>
 									</c:forEach>
 								</p>
 							</div>

+ 1 - 1
src/main/webapp/WEB-INF/view/search.jsp

@@ -92,7 +92,7 @@
 						<la:message key="labels.search_hot_search_word" />
 						<c:forEach var="item" items="${fe:hsw(null, 5)}">
 							<la:link
-								href="/search/search?query=${f:u(item)}${fe:facetQuery()}${fe:geoQuery()}">${f:h(item)}</la:link>
+								href="/search/search?q=${f:u(item)}${fe:facetQuery()}${fe:geoQuery()}">${f:h(item)}</la:link>
 						</c:forEach>
 					</p>
 				</div>

+ 7 - 7
src/main/webapp/WEB-INF/view/searchResults.jsp

@@ -92,7 +92,7 @@
 						<c:forEach var="countEntry" items="${fieldData.valueCountMap}">
 							<c:if test="${countEntry.value != 0 && fe:labelexists(countEntry.key)}">
 								<li class="list-group-item"><la:link
-										href="/search/search?query=${f:u(query)}&additional=label%3a${f:u(countEntry.key)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}"
+										href="/search/search?q=${f:u(q)}&ex_q=label%3a${f:u(countEntry.key)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}"
 									>
 											${f:h(fe:label(countEntry.key))} 
 											<span class="label label-default label-pill pull-right">${f:h(countEntry.value)}</span>
@@ -108,7 +108,7 @@
 					<c:forEach var="queryEntry" items="${facetQueryView.queryMap}">
 						<c:if test="${facetResponse.queryCountMap[queryEntry.value] != 0}">
 							<li class="list-group-item p-l-md"><la:link
-									href="/search/search?query=${f:u(query)}&additional=${f:u(queryEntry.value)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}"
+									href="/search/search?q=${f:u(q)}&ex_q=${f:u(queryEntry.value)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}"
 								>
 									<la:message key="${queryEntry.key}" />
 									<span class="label label-default label-pill pull-right">${f:h(facetResponse.queryCountMap[queryEntry.value])}</span>
@@ -117,9 +117,9 @@
 					</c:forEach>
 				</ul>
 			</c:forEach>
-			<c:if test="${!empty additional}">
+			<c:if test="${!empty ex_q}">
 				<div class="pull-right">
-					<la:link href="/search/search?query=${f:u(query)}" styleClass="btn btn-secondary btn-sm">
+					<la:link href="/search/search?q=${f:u(q)}" styleClass="btn btn-secondary btn-sm">
 						<la:message key="labels.facet_label_reset" />
 					</la:link>
 				</div>
@@ -132,7 +132,7 @@
 		<ul class="pagination">
 			<c:if test="${existPrevPage}">
 				<li class="prev"><la:link aria-label="Previous"
-						href="/search/prev?query=${f:u(query)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}">
+						href="/search/prev?q=${f:u(q)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}">
 					<span aria-hidden="true">&laquo;</span>
 					<span class="sr-only"><la:message key="labels.prev_page" /></span>
 				</la:link></li>
@@ -149,12 +149,12 @@
 					<c:if test="${pageNumber == currentPageNumber && pageNumber >= currentPageNumber - 2 && pageNumber <= currentPageNumber + 2}">class="active"</c:if>
 					>
 					<la:link
-						href="/search/move?query=${f:u(query)}&pn=${f:u(pageNumber)}&num=${f:u(pageSize)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}">${f:h(pageNumber)}</la:link>
+						href="/search/move?q=${f:u(q)}&pn=${f:u(pageNumber)}&num=${f:u(pageSize)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}">${f:h(pageNumber)}</la:link>
 				</li>
 			</c:forEach>
 			<c:if test="${existNextPage}">
 				<li class="next"><la:link aria-label="Next"
-						href="/search/next?query=${f:u(query)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}">
+						href="/search/next?q=${f:u(q)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}${pagingQuery}${fe:facetQuery()}${fe:geoQuery()}">
 					<span class="sr-only"><la:message key="labels.next_page" /></span>
 					<span aria-hidden="true">&raquo;</span>
 				</la:link></li>