yfujita 10 rokov pred
rodič
commit
e1c26661f8

+ 5 - 1
src/main/java/jp/sf/fess/Constants.java

@@ -163,6 +163,10 @@ public class Constants extends CoreLibConstants {
 
     public static final String USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY = "search.use.browser.locale";
 
+    public static final String SUGGEST_SEARCH_LOG_PROPERTY = "suggest.searchlog";
+
+    public static final String PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY = "purge.suggest.searchlog.day";
+
     public static final String AUTH_CIPHER = "authenticationCipher";
 
     public static final String RETURN_PATH = "jp.sf.fess.ReturnPath";
@@ -249,7 +253,7 @@ public class Constants extends CoreLibConstants {
     public static final String SAMBA = "SAMBA";
 
     public static final String[] RESERVED = { "+", "-", "&&", "||", "!", "(",
-            ")", "{", "}", "[", "]", "^", "~", "*", "?", "\\", ";", ":", "/" };
+        ")", "{", "}", "[", "]", "^", "~", "*", "?", "\\", ";", ":", "/" };
 
     public static final Pattern SOLR_FIELD_RESERVED_PATTERN = Pattern
             .compile("([+\\-!\\(\\){}\\[\\]^\"~\\\\:\\p{Zs}]|(&&)|(\\|\\|))"); // "*", "?",

+ 29 - 6
src/main/java/jp/sf/fess/action/IndexAction.java

@@ -54,8 +54,6 @@ import jp.sf.fess.db.exentity.SearchLog;
 import jp.sf.fess.db.exentity.UserInfo;
 import jp.sf.fess.entity.FieldAnalysisResponse;
 import jp.sf.fess.entity.LoginInfo;
-import jp.sf.fess.entity.SpellCheckResponse;
-import jp.sf.fess.entity.SuggestResponse;
 import jp.sf.fess.form.IndexForm;
 import jp.sf.fess.helper.CrawlingConfigHelper;
 import jp.sf.fess.helper.DocumentHelper;
@@ -64,6 +62,7 @@ import jp.sf.fess.helper.HotSearchWordHelper.Range;
 import jp.sf.fess.helper.LabelTypeHelper;
 import jp.sf.fess.helper.OpenSearchHelper;
 import jp.sf.fess.helper.QueryHelper;
+import jp.sf.fess.helper.RoleQueryHelper;
 import jp.sf.fess.helper.SearchLogHelper;
 import jp.sf.fess.helper.SystemHelper;
 import jp.sf.fess.helper.UserInfoHelper;
@@ -72,6 +71,9 @@ import jp.sf.fess.screenshot.ScreenShotManager;
 import jp.sf.fess.service.FavoriteLogService;
 import jp.sf.fess.service.SearchService;
 import jp.sf.fess.suggest.Suggester;
+import jp.sf.fess.suggest.entity.SpellCheckResponse;
+import jp.sf.fess.suggest.entity.SuggestResponse;
+import jp.sf.fess.suggest.service.SuggestService;
 import jp.sf.fess.util.ComponentUtil;
 import jp.sf.fess.util.FacetResponse;
 import jp.sf.fess.util.MoreLikeThisResponse;
@@ -149,6 +151,9 @@ public class IndexAction {
     @Resource
     protected QueryHelper queryHelper;
 
+    @Resource
+    protected RoleQueryHelper roleQueryHelper;
+
     @Resource
     protected UserInfoHelper userInfoHelper;
 
@@ -161,6 +166,9 @@ public class IndexAction {
     @Resource
     protected Suggester suggester;
 
+    @Resource
+    protected SuggestService suggestService;
+
     @Resource
     protected DynamicProperties crawlerProperties;
 
@@ -623,9 +631,16 @@ public class IndexAction {
         }
 
         try {
-            final SuggestResponse suggestResponse = searchService
+            final Set<String> roleSet;
+            if (roleQueryHelper != null) {
+                roleSet = roleQueryHelper.build();
+            } else {
+                roleSet = new HashSet<>();
+            }
+
+            final SuggestResponse suggestResponse = suggestService
                     .getSuggestResponse(indexForm.query, suggestFieldName,
-                            labelList, num);
+                            labelList, new ArrayList<String>(roleSet), num);
 
             if (!suggestResponse.isEmpty()) {
                 suggestResultList.add(suggestResponse);
@@ -682,9 +697,17 @@ public class IndexAction {
         }
 
         try {
-            final SpellCheckResponse spellCheckResponse = searchService
+            final Set<String> roleSet;
+            if (roleQueryHelper != null) {
+                roleSet = roleQueryHelper.build();
+            } else {
+                roleSet = new HashSet<>();
+            }
+
+            final SpellCheckResponse spellCheckResponse = suggestService
                     .getSpellCheckResponse(indexForm.query,
-                            spellCheckFieldName, labelList, num);
+                            spellCheckFieldName, labelList,
+                            new ArrayList<String>(roleSet), num);
 
             if (!spellCheckResponse.isEmpty()) {
                 spellCheckResultList.add(spellCheckResponse);

+ 74 - 60
src/main/java/jp/sf/fess/action/admin/CrawlAction.java

@@ -112,6 +112,10 @@ public class CrawlAction implements Serializable {
                 Constants.DEFAULT_PURGE_BY_BOTS);
         crawlForm.notificationTo = crawlerProperties.getProperty(
                 Constants.NOTIFICATION_TO_PROPERTY, StringUtil.EMPTY);
+        crawlForm.suggestSearchLog = crawlerProperties.getProperty(
+                Constants.SUGGEST_SEARCH_LOG_PROPERTY, Constants.TRUE);
+        crawlForm.purgeSuggestSearchLogDay = crawlerProperties.getProperty(
+                Constants.PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY, "30");
         if (redirect) {
             return "index?redirect=true";
         } else {
@@ -129,74 +133,74 @@ public class CrawlAction implements Serializable {
     @Execute(validator = true, input = "index.jsp")
     public String update() {
         crawlerProperties
-                .setProperty(
-                        Constants.DIFF_CRAWLING_PROPERTY,
-                        crawlForm.diffCrawling != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.diffCrawling) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.DIFF_CRAWLING_PROPERTY,
+                crawlForm.diffCrawling != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.diffCrawling) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties
-                .setProperty(
-                        Constants.USE_ACL_AS_ROLE,
-                        crawlForm.useAclAsRole != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.useAclAsRole) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.USE_ACL_AS_ROLE,
+                crawlForm.useAclAsRole != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.useAclAsRole) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties
-                .setProperty(
-                        Constants.SERVER_ROTATION_PROPERTY,
-                        crawlForm.serverRotation != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.serverRotation) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.SERVER_ROTATION_PROPERTY,
+                crawlForm.serverRotation != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.serverRotation) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties.setProperty(Constants.DAY_FOR_CLEANUP_PROPERTY,
                 crawlForm.dayForCleanup);
         crawlerProperties.setProperty(Constants.CRAWLING_THREAD_COUNT_PROPERTY,
                 crawlForm.crawlingThreadCount);
         crawlerProperties
-                .setProperty(
-                        Constants.SEARCH_LOG_PROPERTY,
-                        crawlForm.searchLog != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.searchLog) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.SEARCH_LOG_PROPERTY,
+                crawlForm.searchLog != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.searchLog) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties
-                .setProperty(
-                        Constants.USER_INFO_PROPERTY,
-                        crawlForm.userInfo != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.userInfo) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.USER_INFO_PROPERTY,
+                crawlForm.userInfo != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.userInfo) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties
-                .setProperty(
-                        Constants.USER_FAVORITE_PROPERTY,
-                        crawlForm.userFavorite != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.userFavorite) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.USER_FAVORITE_PROPERTY,
+                crawlForm.userFavorite != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.userFavorite) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties
-                .setProperty(
-                        Constants.WEB_API_XML_PROPERTY,
-                        crawlForm.webApiXml != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.webApiXml) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.WEB_API_XML_PROPERTY,
+                crawlForm.webApiXml != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.webApiXml) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties
-                .setProperty(
-                        Constants.WEB_API_JSON_PROPERTY,
-                        crawlForm.webApiJson != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.webApiJson) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.WEB_API_JSON_PROPERTY,
+                crawlForm.webApiJson != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.webApiJson) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties.setProperty(Constants.DEFAULT_LABEL_VALUE_PROPERTY,
                 crawlForm.defaultLabelValue);
         crawlerProperties
-                .setProperty(
-                        Constants.APPEND_QUERY_PARAMETER_PROPERTY,
-                        crawlForm.appendQueryParameter != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.appendQueryParameter) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.APPEND_QUERY_PARAMETER_PROPERTY,
+                crawlForm.appendQueryParameter != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.appendQueryParameter) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties.setProperty(
                 Constants.SUPPORTED_SEARCH_FEATURE_PROPERTY,
                 crawlForm.supportedSearch);
@@ -206,12 +210,12 @@ public class CrawlAction implements Serializable {
                 Constants.FAILURE_COUNT_THRESHOLD_PROPERTY,
                 crawlForm.failureCountThreshold);
         crawlerProperties
-                .setProperty(
-                        Constants.WEB_API_HOT_SEARCH_WORD_PROPERTY,
-                        crawlForm.hotSearchWord != null
-                                && Constants.ON
-                                        .equalsIgnoreCase(crawlForm.hotSearchWord) ? Constants.TRUE
-                                : Constants.FALSE);
+        .setProperty(
+                Constants.WEB_API_HOT_SEARCH_WORD_PROPERTY,
+                crawlForm.hotSearchWord != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.hotSearchWord) ? Constants.TRUE
+                        : Constants.FALSE);
         crawlerProperties.setProperty(Constants.CSV_FILE_ENCODING_PROPERTY,
                 crawlForm.csvFileEncoding);
         crawlerProperties.setProperty(Constants.PURGE_SEARCH_LOG_DAY_PROPERTY,
@@ -224,6 +228,16 @@ public class CrawlAction implements Serializable {
                 crawlForm.purgeByBots);
         crawlerProperties.setProperty(Constants.NOTIFICATION_TO_PROPERTY,
                 crawlForm.notificationTo);
+        crawlerProperties
+        .setProperty(
+                Constants.SUGGEST_SEARCH_LOG_PROPERTY,
+                crawlForm.suggestSearchLog != null
+                && Constants.ON
+                .equalsIgnoreCase(crawlForm.suggestSearchLog) ? Constants.TRUE
+                        : Constants.FALSE);
+        crawlerProperties.setProperty(
+                Constants.PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY,
+                crawlForm.purgeSuggestSearchLogDay);
         try {
             crawlerProperties.store();
             SAStrutsUtil.addSessionMessage("success.update_crawler_params");

+ 64 - 38
src/main/java/jp/sf/fess/action/admin/DocumentAction.java

@@ -31,6 +31,9 @@ import jp.sf.fess.form.admin.DocumentForm;
 import jp.sf.fess.helper.JobHelper;
 import jp.sf.fess.helper.SystemHelper;
 import jp.sf.fess.helper.WebManagementHelper;
+import jp.sf.fess.suggest.SuggestConstants;
+import jp.sf.fess.suggest.server.SuggestSolrServer;
+import jp.sf.fess.suggest.service.SuggestService;
 import jp.sf.fess.util.ComponentUtil;
 
 import org.apache.solr.client.solrj.SolrQuery;
@@ -68,9 +71,6 @@ public class DocumentAction implements Serializable {
     @Resource
     protected SolrGroupManager solrGroupManager;
 
-    @Resource
-    protected SolrGroup suggestSolrGroup;
-
     @Resource
     protected WebManagementHelper webManagementHelper;
 
@@ -80,6 +80,11 @@ public class DocumentAction implements Serializable {
     @Resource
     protected JobHelper jobHelper;
 
+    @Resource
+    protected SuggestService suggestService;
+
+    public Map<String, Long> suggestDocumentNums;
+
     public String getHelpLink() {
         return systemHelper.getHelpLink("document");
     }
@@ -124,6 +129,9 @@ public class DocumentAction implements Serializable {
                 documentForm.serverStatusList.add(map);
             }
         }
+
+        suggestDocumentNums = getSuggestDocumentNum();
+
         // select group status
         documentForm.currentServerForSelect = solrProperties
                 .getProperty(SolrLibConstants.SELECT_GROUP);
@@ -174,15 +182,6 @@ public class DocumentAction implements Serializable {
             throw new SSCActionMessagesException(
                     "errors.failed_to_commit_solr_index");
         } else {
-            final boolean isUpdateSolrGroup;
-            final SolrGroup updateSolrGroup = solrGroupManager
-                    .getSolrGroup(QueryType.ADD);
-            if (updateSolrGroup.getGroupName().equals(solrGroup.getGroupName())) {
-                isUpdateSolrGroup = true;
-            } else {
-                isUpdateSolrGroup = false;
-            }
-
             final Thread thread = new Thread(new Runnable() {
                 @Override
                 public void run() {
@@ -190,18 +189,9 @@ public class DocumentAction implements Serializable {
                         final long execTime = System.currentTimeMillis();
                         try {
                             systemHelper.updateStatus(solrGroup, QueryType.ADD);
-                            if (isUpdateSolrGroup) {
-                                systemHelper.updateStatus(suggestSolrGroup,
-                                        QueryType.ADD);
-                            }
                             solrGroup.commit(true, true, false, true);
                             systemHelper.updateStatus(solrGroup,
                                     QueryType.COMMIT);
-                            if (isUpdateSolrGroup) {
-                                systemHelper.updateStatus(suggestSolrGroup,
-                                        QueryType.COMMIT);
-                            }
-
                             if (logger.isInfoEnabled()) {
                                 logger.info("[EXEC TIME] index commit time: "
                                         + (System.currentTimeMillis() - execTime)
@@ -237,15 +227,6 @@ public class DocumentAction implements Serializable {
             throw new SSCActionMessagesException(
                     "errors.failed_to_optimize_solr_index");
         } else {
-            final boolean isUpdateSolrGroup;
-            final SolrGroup updateSolrGroup = solrGroupManager
-                    .getSolrGroup(QueryType.ADD);
-            if (updateSolrGroup.getGroupName().equals(solrGroup.getGroupName())) {
-                isUpdateSolrGroup = true;
-            } else {
-                isUpdateSolrGroup = false;
-            }
-
             final Thread thread = new Thread(new Runnable() {
                 @Override
                 public void run() {
@@ -253,17 +234,9 @@ public class DocumentAction implements Serializable {
                         final long execTime = System.currentTimeMillis();
                         try {
                             systemHelper.updateStatus(solrGroup, QueryType.ADD);
-                            if (isUpdateSolrGroup) {
-                                systemHelper.updateStatus(suggestSolrGroup,
-                                        QueryType.ADD);
-                            }
                             solrGroup.optimize();
                             systemHelper.updateStatus(solrGroup,
                                     QueryType.OPTIMIZE);
-                            if (isUpdateSolrGroup) {
-                                systemHelper.updateStatus(suggestSolrGroup,
-                                        QueryType.OPTIMIZE);
-                            }
                             if (logger.isInfoEnabled()) {
                                 logger.info("[EXEC TIME] index optimize time: "
                                         + (System.currentTimeMillis() - execTime)
@@ -425,6 +398,59 @@ public class DocumentAction implements Serializable {
         return jobHelper.getRunningSessionIdSet();
     }
 
+    protected Map<String, Long> getSuggestDocumentNum() {
+        final Map<String, Long> map = new HashMap<String, Long>();
+        map.put("content", suggestService.getContentDocumentNum());
+        map.put("searchLog", suggestService.getSearchLogDocumentNum());
+        map.put("all", map.get("content") + map.get("searchLog"));
+        return map;
+    }
+
+    @Token(save = false, validate = true)
+    @Execute(validator = true, input = "index")
+    public String deleteSuggest() {
+        final SuggestSolrServer suggestSolrServer = suggestService
+                .getSuggestSolrServer();
+        final String query;
+        if ("content".equals(documentForm.deleteSuggestType)) {
+            query = "*:* NOT " + SuggestConstants.SuggestFieldNames.SEGMENT
+                    + ":0";
+        } else if ("searchLog".equals(documentForm.deleteSuggestType)) {
+            query = SuggestConstants.SuggestFieldNames.SEGMENT + ":0";
+        } else {
+            query = "*:*";
+        }
+
+        final Thread thread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                if (!jobHelper.isCrawlProcessRunning()) {
+                    final long execTime = System.currentTimeMillis();
+                    try {
+                        suggestSolrServer.deleteByQuery(query);
+                        suggestSolrServer.commit();
+                        if (logger.isInfoEnabled()) {
+                            logger.info("[EXEC TIME] suggest index cleanup time: "
+                                    + (System.currentTimeMillis() - execTime)
+                                    + "ms");
+                        }
+                    } catch (final Exception e) {
+                        logger.error("Failed to delete suggest index (query="
+                                + query + ").", e);
+                    }
+                } else {
+                    if (logger.isInfoEnabled()) {
+                        logger.info("could not start index cleanup process"
+                                + " because of running solr process.");
+                    }
+                }
+            }
+        });
+        thread.start();
+        SAStrutsUtil.addSessionMessage("success.delete_solr_index");
+        return showIndex(true);
+    }
+
     private static class SessionIdList<E> extends ArrayList<E> {
 
         private static final long serialVersionUID = 1L;

+ 3 - 24
src/main/java/jp/sf/fess/action/admin/SystemAction.java

@@ -70,9 +70,6 @@ public class SystemAction implements Serializable {
     @Resource
     protected SolrGroupManager solrGroupManager;
 
-    @Resource
-    protected SolrGroup suggestSolrGroup;
-
     @Resource
     protected WebManagementHelper webManagementHelper;
 
@@ -98,23 +95,10 @@ public class SystemAction implements Serializable {
                 groupPropMap.put(groupName, props);
             }
         }
-        final DynamicProperties suggestProps = ComponentUtil
-                .getSolrGroupProperties(suggestSolrGroup.getGroupName());
-        if (suggestProps != null) {
-            groupPropMap.put(suggestSolrGroup.getGroupName(), suggestProps);
-        }
 
         final String[] serverNames = solrGroupManager.getSolrServerNames();
-        final String[] suggestServerNames = suggestSolrGroup.getServerNames();
-        for (int i = 0; i < suggestServerNames.length; i++) {
-            if (StringUtil.isNotBlank(suggestServerNames[i])) {
-                suggestServerNames[i] = suggestSolrGroup.getGroupName() + ":"
-                        + suggestServerNames[i];
-            }
-        }
         final List<String> serverNameList = new ArrayList<String>();
         serverNameList.addAll(Arrays.asList(serverNames));
-        serverNameList.addAll(Arrays.asList(suggestServerNames));
         for (final String name : serverNameList) {
             final String[] names = name.split(":");
             if (names.length == 2) {
@@ -193,11 +177,6 @@ public class SystemAction implements Serializable {
                 groupPropMap.put(groupName, props);
             }
         }
-        final DynamicProperties suggestProps = ComponentUtil
-                .getSolrGroupProperties(suggestSolrGroup.getGroupName());
-        if (suggestProps != null) {
-            groupPropMap.put(suggestSolrGroup.getGroupName(), suggestProps);
-        }
 
         try {
             // server status
@@ -257,14 +236,14 @@ public class SystemAction implements Serializable {
                 }
                 SAStrutsUtil.addSessionMessage("success.start_crawl_process");
                 RequestUtil.getRequest().getSession()
-                        .setAttribute(STARTING_CRAWL_PROCESS, Boolean.TRUE);
+                .setAttribute(STARTING_CRAWL_PROCESS, Boolean.TRUE);
             } else {
                 SAStrutsUtil
-                        .addSessionMessage("success.failed_to_start_crawl_process");
+                .addSessionMessage("success.failed_to_start_crawl_process");
             }
         } else {
             SAStrutsUtil
-                    .addSessionMessage("success.failed_to_start_crawl_process");
+            .addSessionMessage("success.failed_to_start_crawl_process");
         }
         return showIndex(true);
     }

+ 3 - 3
src/main/java/jp/sf/fess/api/json/JsonApiManager.java

@@ -38,10 +38,10 @@ import jp.sf.fess.db.allcommon.CDef;
 import jp.sf.fess.entity.FieldAnalysisResponse;
 import jp.sf.fess.entity.PingResponse;
 import jp.sf.fess.entity.PingResponse.Target;
-import jp.sf.fess.entity.SpellCheckResponse;
-import jp.sf.fess.entity.SuggestResponse;
-import jp.sf.fess.entity.SuggestResponse.SuggestResponseList;
 import jp.sf.fess.service.SearchService;
+import jp.sf.fess.suggest.entity.SpellCheckResponse;
+import jp.sf.fess.suggest.entity.SuggestResponse;
+import jp.sf.fess.suggest.entity.SuggestResponse.SuggestResponseList;
 import jp.sf.fess.util.ComponentUtil;
 import jp.sf.fess.util.FacetResponse;
 import jp.sf.fess.util.FacetResponse.Field;

+ 14 - 14
src/main/java/jp/sf/fess/api/xml/XmlApiManager.java

@@ -37,10 +37,10 @@ import jp.sf.fess.db.allcommon.CDef;
 import jp.sf.fess.entity.FieldAnalysisResponse;
 import jp.sf.fess.entity.PingResponse;
 import jp.sf.fess.entity.PingResponse.Target;
-import jp.sf.fess.entity.SpellCheckResponse;
-import jp.sf.fess.entity.SuggestResponse;
-import jp.sf.fess.entity.SuggestResponse.SuggestResponseList;
 import jp.sf.fess.service.SearchService;
+import jp.sf.fess.suggest.entity.SpellCheckResponse;
+import jp.sf.fess.suggest.entity.SuggestResponse;
+import jp.sf.fess.suggest.entity.SuggestResponse.SuggestResponseList;
 import jp.sf.fess.util.ComponentUtil;
 import jp.sf.fess.util.FacetResponse;
 import jp.sf.fess.util.FacetResponse.Field;
@@ -74,7 +74,7 @@ public class XmlApiManager extends BaseApiManager implements WebApiManager {
     @Override
     public void process(final HttpServletRequest request,
             final HttpServletResponse response, final FilterChain chain)
-            throws IOException, ServletException {
+                    throws IOException, ServletException {
         final String formatType = request.getParameter("type");
         switch (getFormatType(formatType)) {
         case SEARCH:
@@ -206,7 +206,7 @@ public class XmlApiManager extends BaseApiManager implements WebApiManager {
                     if (StringUtil.isNotBlank(name)
                             && entry.getValue() != null
                             && ComponentUtil.getQueryHelper()
-                                    .isApiResponseField(name)) {
+                            .isApiResponseField(name)) {
                         final String tagName = convertTagName(name);
                         buf.append('<');
                         buf.append(tagName);
@@ -523,12 +523,12 @@ public class XmlApiManager extends BaseApiManager implements WebApiManager {
                         .entrySet()) {
 
                     buf.append("<field name=\"")
-                            .append(escapeXml(fEntry.getKey())).append("\">");
+                    .append(escapeXml(fEntry.getKey())).append("\">");
                     for (final Map.Entry<String, List<Map<String, Object>>> aEntry : fEntry
                             .getValue().entrySet()) {
                         buf.append("<analysis name=\"")
-                                .append(escapeXml(aEntry.getKey()))
-                                .append("\">");
+                        .append(escapeXml(aEntry.getKey()))
+                        .append("\">");
                         for (final Map<String, Object> dataMap : aEntry
                                 .getValue()) {
                             buf.append("<token>");
@@ -538,10 +538,10 @@ public class XmlApiManager extends BaseApiManager implements WebApiManager {
                                 final Object value = dEntry.getValue();
                                 if (StringUtil.isNotBlank(key) && value != null) {
                                     buf.append("<value name=\"")
-                                            .append(escapeXml(key))
-                                            .append("\">")
-                                            .append(escapeXml(value))
-                                            .append("</value>");
+                                    .append(escapeXml(key))
+                                    .append("\">")
+                                    .append(escapeXml(value))
+                                    .append("</value>");
                                 }
                             }
                             buf.append("</token>");
@@ -605,8 +605,8 @@ public class XmlApiManager extends BaseApiManager implements WebApiManager {
             for (final Map.Entry<?, ?> entry : ((Map<?, ?>) obj).entrySet()) {
 
                 buf.append("<name>").append(escapeXml(entry.getKey()))
-                        .append("</name><value>")
-                        .append(escapeXml(entry.getValue())).append("</value>");
+                .append("</name><value>")
+                .append(escapeXml(entry.getValue())).append("</value>");
             }
             buf.append("</data>");
         } else if (obj instanceof Date) {

+ 0 - 26
src/main/java/jp/sf/fess/entity/SpellCheckResponse.java

@@ -1,26 +0,0 @@
-/*
- * Copyright 2009-2014 the 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 jp.sf.fess.entity;
-
-import org.apache.solr.client.solrj.response.QueryResponse;
-
-public class SpellCheckResponse extends SuggestResponse {
-    public SpellCheckResponse(final QueryResponse queryResponse, final int num,
-            final String query) {
-        super(queryResponse, num, query);
-    }
-}

+ 0 - 335
src/main/java/jp/sf/fess/entity/SuggestResponse.java

@@ -1,335 +0,0 @@
-/*
- * Copyright 2009-2014 the 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 jp.sf.fess.entity;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
-
-import jp.sf.fess.suggest.SuggestConstants;
-
-import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
-
-public class SuggestResponse implements Map<String, List<String>> {
-    protected String searchQuery;
-
-    protected long execTime;
-
-    private final Map<String, List<String>> parent = new LinkedHashMap<String, List<String>>();
-
-    public SuggestResponse(final QueryResponse queryResponse, final int num,
-            final String query) {
-        if (queryResponse != null) {
-            parent.put(query, new SuggestResponseList(queryResponse, query));
-            setSearchQuery(query);
-        }
-    }
-
-    public String getSearchQuery() {
-        return searchQuery;
-    }
-
-    public void setSearchQuery(final String searchQuery) {
-        this.searchQuery = searchQuery;
-    }
-
-    public long getExecTime() {
-        return execTime;
-    }
-
-    public void setExecTime(final long execTime) {
-        this.execTime = execTime;
-    }
-
-    @Override
-    public int size() {
-        return parent.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return parent.isEmpty();
-    }
-
-    @Override
-    public boolean containsKey(final Object key) {
-        return parent.containsKey(key);
-    }
-
-    @Override
-    public boolean containsValue(final Object value) {
-        return parent.containsValue(value);
-    }
-
-    @Override
-    public List<String> get(final Object key) {
-        return parent.get(key);
-    }
-
-    @Override
-    public List<String> put(final String key, final List<String> value) {
-        return parent.put(key, value);
-    }
-
-    @Override
-    public List<String> remove(final Object key) {
-        return parent.remove(key);
-    }
-
-    @Override
-    public void putAll(final Map<? extends String, ? extends List<String>> m) {
-        parent.putAll(m);
-    }
-
-    @Override
-    public void clear() {
-        parent.clear();
-    }
-
-    @Override
-    public Set<String> keySet() {
-        return parent.keySet();
-    }
-
-    @Override
-    public Collection<List<String>> values() {
-        return parent.values();
-    }
-
-    @Override
-    public Set<java.util.Map.Entry<String, List<String>>> entrySet() {
-        return parent.entrySet();
-    }
-
-    public static class SuggestResponseList implements List<String> {
-        private List<String> parent;
-
-        private final List<Integer> frequencies;
-
-        private final int frequency;
-
-        private final String token;
-
-        private final int startOffset;
-
-        private final int endOffset;
-
-        private final int numFound;
-
-        public SuggestResponseList(final QueryResponse queryResponse,
-                final String query) {
-            final List<String> valueList = new ArrayList<String>();
-            final List<Integer> frequencyList = new ArrayList<Integer>();
-            final SolrDocumentList sdList = queryResponse.getResults();
-            for (final SolrDocument sd : sdList) {
-                final Object text = sd
-                        .getFieldValue(SuggestConstants.SuggestFieldNames.TEXT);
-                final Object freq = sd
-                        .getFieldValue(SuggestConstants.SuggestFieldNames.COUNT);
-                if (text != null && freq != null) {
-                    valueList.add(text.toString());
-                    frequencyList.add(Integer.parseInt(freq.toString()));
-                }
-            }
-            parent = valueList;
-            frequencies = frequencyList;
-            frequency = 1;
-            token = query;
-            startOffset = 0;
-            endOffset = query.length();
-            numFound = (int) queryResponse.getResults().getNumFound();
-        }
-
-        public SuggestResponseList(final Suggestion suggestion) {
-            parent = suggestion.getAlternatives();
-            if (parent == null) {
-                parent = Collections.emptyList();
-            }
-            frequencies = suggestion.getAlternativeFrequencies();
-            frequency = suggestion.getOriginalFrequency();
-            token = suggestion.getToken();
-            startOffset = suggestion.getStartOffset();
-            endOffset = suggestion.getEndOffset();
-            numFound = suggestion.getNumFound();
-        }
-
-        public List<Integer> getFrequencies() {
-            return frequencies;
-        }
-
-        public int getFrequency() {
-            return frequency;
-        }
-
-        public String getToken() {
-            return token;
-        }
-
-        public int getStartOffset() {
-            return startOffset;
-        }
-
-        public int getEndOffset() {
-            return endOffset;
-        }
-
-        public int getNumFound() {
-            return numFound;
-        }
-
-        @Override
-        public int size() {
-            return parent.size();
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return parent.isEmpty();
-        }
-
-        @Override
-        public boolean contains(final Object o) {
-            return parent.contains(o);
-        }
-
-        @Override
-        public Iterator<String> iterator() {
-            return parent.iterator();
-        }
-
-        @Override
-        public Object[] toArray() {
-            return parent.toArray();
-        }
-
-        @Override
-        public <T> T[] toArray(final T[] a) {
-            return parent.toArray(a);
-        }
-
-        @Override
-        public boolean add(final String e) {
-            return parent.add(e);
-        }
-
-        @Override
-        public boolean remove(final Object o) {
-            return parent.remove(o);
-        }
-
-        @Override
-        public boolean containsAll(final Collection<?> c) {
-            return parent.containsAll(c);
-        }
-
-        @Override
-        public boolean addAll(final Collection<? extends String> c) {
-            return parent.addAll(c);
-        }
-
-        @Override
-        public boolean addAll(final int index,
-                final Collection<? extends String> c) {
-            return parent.addAll(index, c);
-        }
-
-        @Override
-        public boolean removeAll(final Collection<?> c) {
-            return parent.removeAll(c);
-        }
-
-        @Override
-        public boolean retainAll(final Collection<?> c) {
-            return parent.retainAll(c);
-        }
-
-        @Override
-        public void clear() {
-            parent.clear();
-        }
-
-        @Override
-        public String get(final int index) {
-            return parent.get(index);
-        }
-
-        @Override
-        public String set(final int index, final String element) {
-            return parent.set(index, element);
-        }
-
-        @Override
-        public void add(final int index, final String element) {
-            parent.add(index, element);
-        }
-
-        @Override
-        public String remove(final int index) {
-            return parent.remove(index);
-        }
-
-        @Override
-        public int indexOf(final Object o) {
-            return parent.indexOf(o);
-        }
-
-        @Override
-        public int lastIndexOf(final Object o) {
-            return parent.lastIndexOf(o);
-        }
-
-        @Override
-        public ListIterator<String> listIterator() {
-            return parent.listIterator();
-        }
-
-        @Override
-        public ListIterator<String> listIterator(final int index) {
-            return parent.listIterator(index);
-        }
-
-        @Override
-        public List<String> subList(final int fromIndex, final int toIndex) {
-            return parent.subList(fromIndex, toIndex);
-        }
-
-        @Override
-        public String toString() {
-            return "SuggestResponseList [parent=" + parent + ", frequencies="
-                    + frequencies + ", frequency=" + frequency + ", token="
-                    + token + ", startOffset=" + startOffset + ", endOffset="
-                    + endOffset + ", numFound=" + numFound + "]";
-        }
-
-    }
-
-    @Override
-    public String toString() {
-        return "SuggestResponse [searchQuery=" + searchQuery + ", execTime="
-                + execTime + ", parent=" + parent + "]";
-    }
-
-}

+ 0 - 17
src/main/java/jp/sf/fess/exec/Crawler.java

@@ -94,9 +94,6 @@ public class Crawler implements Serializable {
     @Resource
     protected SolrGroupManager solrGroupManager;
 
-    @Resource
-    SolrGroup suggestSolrGroup;
-
     @Binding(bindingType = BindingType.MAY)
     @Resource
     protected ScreenShotManager screenShotManager;
@@ -531,13 +528,6 @@ public class Crawler implements Serializable {
                 statusPolicy.activate(QueryType.OPTIMIZE, serverName);
             }
         }
-        final StatusPolicy suggestStatusPolicy = suggestSolrGroup
-                .getStatusPolicy();
-        for (final String serverName : suggestSolrGroup.getServerNames()) {
-            if (suggestStatusPolicy.isActive(QueryType.OPTIMIZE, serverName)) {
-                suggestStatusPolicy.activate(QueryType.OPTIMIZE, serverName);
-            }
-        }
 
         if (logger.isInfoEnabled()) {
             logger.info("[EXEC TIME] index optimize time: " + startTime + "ms");
@@ -564,13 +554,6 @@ public class Crawler implements Serializable {
                 statusPolicy.activate(QueryType.COMMIT, serverName);
             }
         }
-        final StatusPolicy suggestStatusPolicy = suggestSolrGroup
-                .getStatusPolicy();
-        for (final String serverName : suggestSolrGroup.getServerNames()) {
-            if (suggestStatusPolicy.isActive(QueryType.COMMIT, serverName)) {
-                suggestStatusPolicy.activate(QueryType.COMMIT, serverName);
-            }
-        }
 
         if (logger.isInfoEnabled()) {
             logger.info("[EXEC TIME] index commit time: " + startTime + "ms");

+ 2 - 2
src/main/java/jp/sf/fess/filter/AdLoginInfoFilter.java

@@ -85,8 +85,8 @@ public class AdLoginInfoFilter implements Filter {
                 final String servletPath = ((HttpServletRequest) request)
                         .getServletPath();
                 if (redirectLoginError && "/index.do".equals(servletPath)) {
-                    ((HttpServletResponse) response)
-                            .sendRedirect("/n2search/error/badRequest");
+                    ((HttpServletResponse) response).sendRedirect(httpRequest
+                            .getContextPath() + "error/badRequest");
                     return;
                 }
             }

+ 6 - 0
src/main/java/jp/sf/fess/form/admin/CrawlForm.java

@@ -95,4 +95,10 @@ public class CrawlForm implements Serializable {
 
     @Maxbytelength(maxbytelength = 1000)
     public String notificationTo;
+
+    @Maxbytelength(maxbytelength = 10)
+    public String suggestSearchLog;
+
+    @IntRange(min = 0, max = 100000)
+    public String purgeSuggestSearchLogDay;
 }

+ 3 - 0
src/main/java/jp/sf/fess/form/admin/DocumentForm.java

@@ -48,4 +48,7 @@ public class DocumentForm implements Serializable {
 
     @Required(target = "startSolrInstance,stopSolrInstance,reloadSolrInstance")
     public String solrInstanceName;
+
+    @Required(target = "deleteSuggest")
+    public String deleteSuggestType;
 }

+ 4 - 0
src/main/java/jp/sf/fess/helper/SearchLogHelper.java

@@ -30,6 +30,7 @@ import jp.sf.fess.db.exbhv.pmbean.FavoriteUrlCountPmb;
 import jp.sf.fess.db.exentity.ClickLog;
 import jp.sf.fess.db.exentity.SearchLog;
 import jp.sf.fess.db.exentity.customize.FavoriteUrlCount;
+import jp.sf.fess.suggest.service.SuggestService;
 
 import org.codelibs.core.util.DynamicProperties;
 import org.codelibs.robot.util.LruHashMap;
@@ -52,6 +53,9 @@ public abstract class SearchLogHelper {
 
     protected Map<String, Long> userInfoCache;
 
+    @Resource
+    protected SuggestService suggestService;
+
     @InitMethod
     public void init() {
         userInfoCache = new LruHashMap<String, Long>(userInfoCacheSize);

+ 28 - 0
src/main/java/jp/sf/fess/helper/impl/SearchLogHelperImpl.java

@@ -30,6 +30,7 @@ import jp.sf.fess.db.exbhv.ClickLogBhv;
 import jp.sf.fess.db.exbhv.SearchLogBhv;
 import jp.sf.fess.db.exbhv.UserInfoBhv;
 import jp.sf.fess.db.exentity.ClickLog;
+import jp.sf.fess.db.exentity.SearchFieldLog;
 import jp.sf.fess.db.exentity.SearchLog;
 import jp.sf.fess.db.exentity.UserInfo;
 import jp.sf.fess.helper.DocumentHelper;
@@ -81,6 +82,18 @@ public class SearchLogHelperImpl extends SearchLogHelper {
             botNames = value.split(",");
         }
 
+        final boolean suggestAvailable = Constants.TRUE
+                .equals(crawlerProperties.getProperty(
+                        Constants.SUGGEST_SEARCH_LOG_PROPERTY, Constants.TRUE));
+        final String dayForCleanupStr = crawlerProperties.getProperty(
+                Constants.PURGE_SUGGEST_SEARCH_LOG_DAY_PROPERTY, "30");
+        int dayForCleanup = -1;
+        try {
+            dayForCleanup = Integer.parseInt(dayForCleanupStr);
+        } catch (final NumberFormatException e) {
+        }
+
+        boolean addedSuggest = false;
         final Map<String, UserInfo> userInfoMap = new HashMap<String, UserInfo>();
         for (final SearchLog searchLog : queue) {
             boolean add = true;
@@ -102,8 +115,23 @@ public class SearchLogHelperImpl extends SearchLogHelper {
                     userInfoMap.put(code, userInfo);
                 }
                 searchLogList.add(searchLog);
+
+                if (suggestAvailable && searchLog.getHitCount() > 0) {
+                    final List<SearchFieldLog> searchFieldLogList = searchLog
+                            .getSearchFieldLogList();
+                    for (final SearchFieldLog searchFieldLog : searchFieldLogList) {
+                        if ("solrQuery".equals(searchFieldLog.getName())) {
+                            suggestService.addSolrParams(
+                                    searchFieldLog.getValue(), dayForCleanup);
+                            addedSuggest = true;
+                        }
+                    }
+                }
             }
         }
+        if (addedSuggest) {
+            suggestService.commit();
+        }
 
         if (!userInfoMap.isEmpty()) {
             final List<UserInfo> insertList = new ArrayList<UserInfo>(

+ 0 - 99
src/main/java/jp/sf/fess/service/SearchService.java

@@ -17,9 +17,7 @@
 package jp.sf.fess.service;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -36,14 +34,9 @@ import jp.sf.fess.entity.MoreLikeThisInfo;
 import jp.sf.fess.entity.PingResponse;
 import jp.sf.fess.entity.SearchQuery;
 import jp.sf.fess.entity.SearchQuery.SortField;
-import jp.sf.fess.entity.SpellCheckResponse;
-import jp.sf.fess.entity.SuggestResponse;
 import jp.sf.fess.helper.QueryHelper;
 import jp.sf.fess.helper.RoleQueryHelper;
 import jp.sf.fess.solr.FessSolrQueryException;
-import jp.sf.fess.suggest.SpellChecker;
-import jp.sf.fess.suggest.SuggestConstants;
-import jp.sf.fess.suggest.Suggester;
 import jp.sf.fess.util.ComponentUtil;
 import jp.sf.fess.util.QueryResponseList;
 
@@ -64,21 +57,12 @@ public class SearchService implements Serializable {
     @Resource
     protected SolrGroupManager solrGroupManager;
 
-    @Resource
-    protected SolrGroup suggestSolrGroup;
-
     @Resource
     protected QueryHelper queryHelper;
 
     @Resource
     protected RoleQueryHelper roleQueryHelper;
 
-    @Resource
-    protected Suggester suggester;
-
-    @Resource
-    protected SpellChecker spellChecker;
-
     public PingResponse ping() {
         final SolrGroup solrGroup = solrGroupManager
                 .getSolrGroup(QueryType.QUERY);
@@ -291,89 +275,6 @@ public class SearchService implements Serializable {
         return queryResponseList;
     }
 
-    public SuggestResponse getSuggestResponse(final String q,
-            final List<String> fieldNames, final List<String> labels,
-            final int rows) {
-
-        final Set<String> roleSet;
-        if (roleQueryHelper != null) {
-            roleSet = roleQueryHelper.build();
-        } else {
-            roleSet = new HashSet<>();
-        }
-
-        final List<String> roleList = new ArrayList<>(roleSet); // TODO
-        final String suggestQuery = suggester.buildSuggestQuery(q, fieldNames,
-                labels, roleList);
-
-        final long startTime = System.currentTimeMillis();
-
-        QueryResponse queryResponse = null;
-        final SolrQuery solrQuery = new SolrQuery();
-        if (StringUtil.isNotBlank(suggestQuery)) {
-            // query
-            solrQuery.setQuery(suggestQuery);
-            // size
-            solrQuery.setRows(rows);
-            //sort
-            solrQuery.setSort(SuggestConstants.SuggestFieldNames.COUNT,
-                    SolrQuery.ORDER.desc);
-
-            if (queryHelper.getTimeAllowed() >= 0) {
-                solrQuery.setTimeAllowed(queryHelper.getTimeAllowed());
-            }
-
-            queryResponse = suggestSolrGroup.query(solrQuery,
-                    SolrRequest.METHOD.POST);
-        }
-        final long execTime = System.currentTimeMillis() - startTime;
-        final SuggestResponse suggestResponse = new SuggestResponse(
-                queryResponse, rows, q);
-        suggestResponse.setExecTime(execTime);
-        return suggestResponse;
-    }
-
-    public SpellCheckResponse getSpellCheckResponse(final String q,
-            final List<String> fieldNames, final List<String> labels,
-            final int rows) {
-        final Set<String> roleSet;
-        if (roleQueryHelper != null) {
-            roleSet = roleQueryHelper.build();
-        } else {
-            roleSet = new HashSet<>();
-        }
-
-        final List<String> roleList = new ArrayList<>(roleSet);
-        final String spellCheckQuery = spellChecker.buildSpellCheckQuery(q,
-                fieldNames, labels, roleList);
-
-        final long startTime = System.currentTimeMillis();
-
-        QueryResponse queryResponse = null;
-        final SolrQuery solrQuery = new SolrQuery();
-        if (StringUtil.isNotBlank(spellCheckQuery)) {
-            // query
-            solrQuery.setQuery(spellCheckQuery);
-            // size
-            solrQuery.setRows(rows);
-            //sort
-            solrQuery.setSort(SuggestConstants.SuggestFieldNames.COUNT,
-                    SolrQuery.ORDER.desc);
-
-            if (queryHelper.getTimeAllowed() >= 0) {
-                solrQuery.setTimeAllowed(queryHelper.getTimeAllowed());
-            }
-
-            queryResponse = suggestSolrGroup.query(solrQuery,
-                    SolrRequest.METHOD.POST);
-        }
-        final long execTime = System.currentTimeMillis() - startTime;
-        final SpellCheckResponse spellCheckResponse = new SpellCheckResponse(
-                queryResponse, rows, q);
-        spellCheckResponse.setExecTime(execTime);
-        return spellCheckResponse;
-    }
-
     public FieldAnalysisResponse getFieldAnalysisResponse(
             final String[] fieldNames, final String fieldValue) {
         final FieldAnalysisRequest request = new FieldAnalysisRequest();

+ 0 - 1
src/main/resources/app.dicon

@@ -7,7 +7,6 @@
 	<include path="dbflute.dicon"/>
 
 	<include path="fess.dicon"/>
-	<include path="fess_suggest.dicon"/>
 	<include path="fess_job.dicon"/>
 	<include path="fess_api.dicon"/>
 	<include path="fess_dict.dicon"/>

+ 7 - 0
src/main/resources/application.properties

@@ -681,6 +681,13 @@ labels.system_index_status=Index Status
 labels.crawler_status_title=Crawler Status
 labels.crawler_sessionid_all=All
 labels.no_available_solr_servers=No available Solr server.
+labels.suggest_document_title=Added Suggest Docs
+labels.suggest_type=type
+labels.suggest_type_all=all
+labels.suggest_type_content=content
+labels.suggest_type_searchlog=search words
+labels.suggest_search_log_enabled=Suggest by Search Words
+labels.purge_suggest_search_log_day=Purge Suggest Docs by Search Words
 
 # view/admin/crawlingSession/confirm.jsp
 labels.crawling_session_title=Session Information

+ 7 - 0
src/main/resources/application_ja.properties

@@ -681,6 +681,13 @@ labels.system_index_status=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u72b6\u614b
 labels.crawler_status_title=\u30af\u30ed\u30fc\u30e9\u30fc\u72b6\u614b
 labels.crawler_sessionid_all=\u3059\u3079\u3066
 labels.no_available_solr_servers=\u5229\u7528\u53ef\u80fd\u306aSolr\u30b5\u30fc\u30d0\u304c\u3042\u308a\u307e\u305b\u3093\u3002
+labels.suggest_document_title=\u8FFD\u52A0\u3055\u308C\u305F\u30B5\u30B8\u30A7\u30B9\u30C8\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8
+labels.suggest_type=\u7A2E\u5225
+labels.suggest_type_all=\u3059\u3079\u3066
+labels.suggest_type_content=\u30B3\u30F3\u30C6\u30F3\u30C4
+labels.suggest_type_searchlog=\u691C\u7D22\u30ED\u30B0
+labels.suggest_search_log_enabled=\u691C\u7D22\u8A9E\u30B5\u30B8\u30A7\u30B9\u30C8
+labels.purge_suggest_search_log_day=\u691C\u7D22\u8A9E\u30B5\u30B8\u30A7\u30B9\u30C8\u306E\u6709\u52B9\u671F\u9650
 
 # view/admin/crawlingSession/confirm.jsp
 labels.crawling_session_title=\u30bb\u30c3\u30b7\u30e7\u30f3\u60c5\u5831

+ 1 - 0
src/main/resources/fess.dicon

@@ -4,6 +4,7 @@
 <components>
 	<include path="solrlib.dicon"/>
 	<include path="fess_ds.dicon"/>
+	<include path="fess_suggest.dicon"/>
 
 	<component name="crawlerProperties" class="org.codelibs.core.util.DynamicProperties">
 		<arg>

+ 13 - 55
src/main/resources/fess_suggest.dicon

@@ -45,63 +45,9 @@
 		</initMethod>
 	</component>
 
-	<!-- Solr Group Configuration -->
-	<component name="suggestSolrProperties" class="org.codelibs.core.util.DynamicProperties">
-		<arg>
-			@jp.sf.fess.util.ResourceUtil@getConfPath("solr-suggest.properties")
-		</arg>
-	</component>
-	<component name="suggestSolrGroupProperties" class="org.codelibs.core.util.DynamicProperties">
-		<arg>
-			@jp.sf.fess.util.ResourceUtil@getConfPath("suggestSolrGroup.properties")
-		</arg>
-	</component>
-
-
-	<component name="suggestSolrGroup" class="org.codelibs.solr.lib.SolrGroup">
-		<!-- Note: groupName cannot include ".". -->
-		<property name="groupName">"suggestSolrGroup"</property>
-		<property name="statusPolicy">
-			<component class="jp.sf.fess.solr.policy.FessStatusPolicy">
-				<property name="solrGroupProperties">suggestSolrGroupProperties</property>
-				<property name="minSelectServer">1</property>
-				<property name="minUpdateServer">1</property>
-				<property name="retrySelectQueryInterval">500</property>
-				<property name="retryUpdateQueryInterval">500</property>
-				<property name="maxErrorCount">3</property>
-				<property name="maxRetryUpdateQueryCount">3</property>
-				<property name="maxRetrySelectQueryCount">3</property>
-			</component>
-		</property>
-		<initMethod name="addServer">
-			<!-- Note: the server name cannot include ".". -->
-			<arg>"suggestSolrServer"</arg><!-- Group Name -->
-			<arg>suggestSolrServer</arg><!-- Solr Server -->
-		</initMethod>
-	</component>
-
-	<component name="clientConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager">
-		<arg>10</arg><!-- timeToLive -->
-		<arg>@java.util.concurrent.TimeUnit@MINUTES</arg><!-- tunit -->
-		<property name="maxTotal">50</property>
-		<property name="defaultMaxPerRoute">2</property>
-		<destroyMethod name="shutdown"></destroyMethod>
-	</component>
-	<component name="connectionMonitorTarget" class="org.codelibs.robot.client.http.HcConnectionMonitorTarget">
-		<arg>clientConnectionManager</arg>
-		<arg>300000</arg>
-	</component>
-	<component name="connectionMonitorTask">
-		@org.seasar.extension.timer.TimeoutManager@getInstance()
-			.addTimeoutTarget(
-                connectionMonitorTarget,
-                10,
-                true)
-		<destroyMethod name="cancel"></destroyMethod>
-	</component>
 
 	<!-- Solr Server Configuration -->
-	<component name="suggestSolrServer" class="org.codelibs.solr.lib.server.SolrLibHttpSolrServer">
+	<component name="suggestSolrLibSolrServer" class="org.codelibs.solr.lib.server.SolrLibHttpSolrServer">
 		<!-- Solr Server URL -->
 		<arg>"http://localhost:8080/solr/core1-suggest"</arg>
 		<property name="requestWriter">new org.apache.solr.client.solrj.impl.BinaryRequestWriter()</property>
@@ -126,4 +72,16 @@
 		<destroyMethod name="shutdown"></destroyMethod>
 	</component>
 
+
+	<component name="suggestSolrServer" class="jp.sf.fess.suggest.server.SuggestSolrServer">
+		<arg>
+			suggestSolrLibSolrServer
+		</arg>
+	</component>
+	<component name="suggestService" class="jp.sf.fess.suggest.service.SuggestService">
+		<arg> suggester </arg>
+		<arg> spellchecker </arg>
+		<arg> suggestSolrServer </arg>
+	</component>
+
 </components>

+ 16 - 0
src/main/webapp/WEB-INF/view/admin/crawl/index.jsp

@@ -207,6 +207,22 @@
 						<html:text property="failureCountThreshold" styleClass="small"/>
 					</td>
 				</tr>
+				<tr>
+					<th style="width:200px;">
+						<bean:message key="labels.suggest_search_log_enabled"/>
+					</th>
+					<td>
+						<html:checkbox property="suggestSearchLog"/><bean:message key="labels.enabled"/>
+					</td>
+				</tr>
+				<tr>
+					<th>
+						<bean:message key="labels.purge_suggest_search_log_day"/>
+					</th>
+					<td>
+						<html:text property="purgeSuggestSearchLogDay" styleClass="small"/>
+					</td>
+				</tr>
 			</tbody>
 			<tfoot>
 				<tr>

+ 59 - 1
src/main/webapp/WEB-INF/view/admin/document/index.jsp

@@ -141,7 +141,65 @@
 					</tbody>
 				</table>
 			</div>
-</c:if>
+			<div style="margin-top: 5px;">
+				<h3>
+					<bean:message key="labels.suggest_document_title" />
+				</h3>
+				<table class="bordered-table zebra-striped">
+					<thead>
+						<tr>
+							<th style="width:200px;"><bean:message key="labels.suggest_type" /></th>
+							<th><bean:message key="labels.solr_num_of_docs" /></th>
+							<th></th>
+						</tr>
+					</thead>
+					<tbody>
+						<tr>
+							<td><bean:message key="labels.suggest_type_all" /></td>
+							<td align="center">${suggestDocumentNums.all}</td>
+							<td align="center">
+								<s:form>
+									<html:hidden property="deleteSuggestType"
+										value="all" />
+									<html:submit styleClass="btn" property="deleteSuggest"
+										disabled="${solrProcessRunning}">
+										<bean:message key="labels.solr_action_delete" />
+									</html:submit>
+								</s:form>
+							</td>
+						</tr>
+						<tr>
+							<td><bean:message key="labels.suggest_type_content" /></td>
+							<td align="center">${suggestDocumentNums.content}</td>
+							<td align="center">
+								<s:form>
+									<html:hidden property="deleteSuggestType"
+										value="content" />
+									<html:submit styleClass="btn" property="deleteSuggest"
+										disabled="${solrProcessRunning}">
+										<bean:message key="labels.solr_action_delete" />
+									</html:submit>
+								</s:form>
+							</td>
+						</tr>
+						<tr>
+							<td><bean:message key="labels.suggest_type_searchlog" /></td>
+							<td align="center">${suggestDocumentNums.searchLog}</td>
+							<td align="center">
+								<s:form>
+									<html:hidden property="deleteSuggestType"
+										value="searchLog" />
+									<html:submit styleClass="btn" property="deleteSuggest"
+										disabled="${solrProcessRunning}">
+										<bean:message key="labels.solr_action_delete" />
+									</html:submit>
+								</s:form>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</div>
+			</c:if>
 		</div>
 
 		<c:if test="${solrProcessRunning}">