fix #1873 add aggregations for search logs

This commit is contained in:
Shinsuke Sugaya 2018-10-18 17:17:06 +09:00
parent eae48aba61
commit 31f64e09e8
10 changed files with 468 additions and 77 deletions

View file

@ -26,8 +26,28 @@ public class SearchLogPager implements Serializable {
public static final String LOG_TYPE_SEARCH = "search";
public static final String LOG_TYPE_SEARCH_COUNT_HOUR = "search_count_hour_agg";
public static final String LOG_TYPE_SEARCH_COUNT_DAY = "search_count_day_agg";
public static final String LOG_TYPE_SEARCH_USER_HOUR = "search_user_hour_agg";
public static final String LOG_TYPE_SEARCH_USER_DAY = "search_user_day_agg";
public static final String LOG_TYPE_SEARCH_REQTIMEAVG_HOUR = "search_reqtimeavg_hour_agg";
public static final String LOG_TYPE_SEARCH_REQTIMEAVG_DAY = "search_reqtimeavg_day_agg";
public static final String LOG_TYPE_SEARCH_KEYWORD = "search_keyword_agg";
public static final String LOG_TYPE_SEARCH_ZEROHIT = "search_zerohit_agg";
public static final String LOG_TYPE_SEARCH_ZEROCLICK = "search_zeroclick_agg";
public static final String LOG_TYPE_CLICK = "click";
public static final String LOG_TYPE_CLICK_TOP = "click_top_agg";
public static final String LOG_TYPE_FAVORITE = "favorite";
public static final int DEFAULT_PAGE_SIZE = 20;

View file

@ -15,12 +15,17 @@
*/
package org.codelibs.fess.app.service;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
@ -28,6 +33,10 @@ import org.codelibs.core.beans.util.BeanUtil;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.Constants;
import org.codelibs.fess.app.pager.SearchLogPager;
import org.codelibs.fess.es.log.allcommon.EsPagingResultBean;
import org.codelibs.fess.es.log.cbean.ClickLogCB;
import org.codelibs.fess.es.log.cbean.FavoriteLogCB;
import org.codelibs.fess.es.log.cbean.SearchLogCB;
import org.codelibs.fess.es.log.exbhv.ClickLogBhv;
import org.codelibs.fess.es.log.exbhv.FavoriteLogBhv;
import org.codelibs.fess.es.log.exbhv.SearchLogBhv;
@ -38,12 +47,29 @@ import org.codelibs.fess.exception.FessSystemException;
import org.codelibs.fess.helper.SystemHelper;
import org.codelibs.fess.mylasta.direction.FessConfig;
import org.codelibs.fess.taglib.FessFunctions;
import org.dbflute.cbean.result.PagingResultBean;
import org.dbflute.optional.OptionalEntity;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SearchLogService {
private static final String COUNT = "count";
private static final String KEY = "key";
private static final String ID = "id";
private static final String USER_INFO_ID = "userInfoId";
private static final String QUERY_TIME = "queryTime";
private static final Logger logger = LoggerFactory.getLogger(SearchLogService.class);
@Resource
@ -67,91 +93,205 @@ public class SearchLogService {
});
}
public PagingResultBean<?> getSearchLogList(final SearchLogPager pager) {
final PagingResultBean<?> list;
if (SearchLogPager.LOG_TYPE_CLICK.equalsIgnoreCase(pager.logType)) {
list = clickLogBhv.selectPage(cb -> {
public List<?> getSearchLogList(final SearchLogPager pager) {
final EsPagingResultBean<?> list;
if (SearchLogPager.LOG_TYPE_CLICK.equalsIgnoreCase(pager.logType)
|| SearchLogPager.LOG_TYPE_CLICK_TOP.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) clickLogBhv.selectPage(cb -> {
cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
cb.query().addOrderBy_RequestedAt_Desc();
if (StringUtil.isNotBlank(pager.queryId)) {
cb.query().setQueryId_Term(pager.queryId);
}
if (StringUtil.isNotBlank(pager.userSessionId)) {
cb.query().setUserSessionId_Term(pager.userSessionId);
}
if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
String[] values = pager.requestedTimeRange.split(" - ");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
if (values.length > 0) {
cb.query().setRequestedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
}
if (values.length > 1) {
cb.query().setRequestedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to parse " + pager.requestedTimeRange, e);
}
}
}
createClickLogCondition(pager, cb);
});
} else if (SearchLogPager.LOG_TYPE_CLICK_TOP.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) clickLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createClickLogCondition(pager, cb);
cb.aggregation().filter("top_click_filter", null, null, aggs -> {
aggs.setUrl_Count();
});
});
} else if (SearchLogPager.LOG_TYPE_FAVORITE.equalsIgnoreCase(pager.logType)) {
list = favoriteLogBhv.selectPage(cb -> {
list = (EsPagingResultBean<?>) favoriteLogBhv.selectPage(cb -> {
cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
cb.query().addOrderBy_CreatedAt_Desc();
if (StringUtil.isNotBlank(pager.queryId)) {
cb.query().setQueryId_Term(pager.queryId);
}
if (StringUtil.isNotBlank(pager.userSessionId)) {
cb.query().setUserInfoId_Term(pager.userSessionId);
}
if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
String[] values = pager.requestedTimeRange.split(" - ");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
if (values.length > 0) {
cb.query().setCreatedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
}
if (values.length > 1) {
cb.query().setCreatedAt_LessEqual(parseDateTime(values[1], formatter));
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to parse " + pager.requestedTimeRange, e);
}
}
}
createFavoriteLogCondition(pager, cb);
});
} else if (SearchLogPager.LOG_TYPE_SEARCH_COUNT_HOUR.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_COUNT_HOUR, op -> {
op.dateHistogramInterval(DateHistogramInterval.HOUR);
op.minDocCount(0);
op.order(BucketOrder.key(true));
}, null);
});
final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_COUNT_HOUR);
final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
map.put(COUNT, e.getDocCount());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_COUNT_DAY.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_COUNT_DAY, op -> {
op.dateHistogramInterval(DateHistogramInterval.DAY);
op.minDocCount(0);
op.order(BucketOrder.key(true));
}, null);
});
final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_COUNT_DAY);
final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
map.put(COUNT, e.getDocCount());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_USER_HOUR.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_USER_HOUR, op -> {
op.dateHistogramInterval(DateHistogramInterval.HOUR);
op.subAggregation(AggregationBuilders.cardinality(USER_INFO_ID).field(USER_INFO_ID));
op.minDocCount(0);
op.order(BucketOrder.key(true));
}, null);
});
final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_USER_HOUR);
final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
final Cardinality value = e.getAggregations().get(USER_INFO_ID);
map.put(COUNT, value.getValue());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_USER_DAY.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_USER_DAY, op -> {
op.dateHistogramInterval(DateHistogramInterval.DAY);
op.subAggregation(AggregationBuilders.cardinality(USER_INFO_ID).field(USER_INFO_ID));
op.minDocCount(0);
op.order(BucketOrder.key(true));
}, null);
});
final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_USER_DAY);
final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
final Cardinality value = e.getAggregations().get(USER_INFO_ID);
map.put(COUNT, value.getValue());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_HOUR.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_HOUR, op -> {
op.dateHistogramInterval(DateHistogramInterval.HOUR);
op.subAggregation(AggregationBuilders.avg(QUERY_TIME).field(QUERY_TIME));
op.minDocCount(0);
op.order(BucketOrder.key(true));
}, null);
});
final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_HOUR);
final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
final Avg value = e.getAggregations().get(QUERY_TIME);
map.put(COUNT, value.getValueAsString());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_DAY.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_DAY, op -> {
op.dateHistogramInterval(DateHistogramInterval.DAY);
op.subAggregation(AggregationBuilders.avg(QUERY_TIME).field(QUERY_TIME));
op.minDocCount(0);
op.order(BucketOrder.key(true));
}, null);
});
final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_DAY);
final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
final Avg value = e.getAggregations().get(QUERY_TIME);
map.put(COUNT, value.getValueAsString());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_KEYWORD.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.aggregation().setSearchWord_Terms(SearchLogPager.LOG_TYPE_SEARCH_KEYWORD, op -> {
op.size(pager.getPageSize());
}, null);
});
final Terms agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_KEYWORD);
final List<? extends Terms.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
map.put(COUNT, e.getDocCount());
return map;
}).collect(Collectors.toList());
} else if (SearchLogPager.LOG_TYPE_SEARCH_ZEROHIT.equalsIgnoreCase(pager.logType)) {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.fetchFirst(0);
createSearchLogCondition(pager, cb);
cb.query().setHitCount_Equal(0L);
cb.aggregation().setSearchWord_Terms(SearchLogPager.LOG_TYPE_SEARCH_ZEROHIT, op -> {
op.size(pager.getPageSize());
}, null);
});
final Terms agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_ZEROHIT);
final List<? extends Terms.Bucket> buckets = agg.getBuckets();
updatePagerByAgg(pager, buckets.size());
return buckets.stream().map(e -> {
final Map<String, Object> map = new HashMap<>();
map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
map.put(KEY, e.getKeyAsString());
map.put(COUNT, e.getDocCount());
return map;
}).collect(Collectors.toList());
// } else if (SearchLogPager.LOG_TYPE_SEARCH_ZEROCLICK.equalsIgnoreCase(pager.logType)) {
// list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
// cb.fetchFirst(0);
// createSearchLogCondition(pager, cb);
// // TODO 0 clicked
// });
} else {
list = searchLogBhv.selectPage(cb -> {
list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
cb.query().addOrderBy_RequestedAt_Desc();
if (StringUtil.isNotBlank(pager.queryId)) {
cb.query().setQueryId_Term(pager.queryId);
}
if (StringUtil.isNotBlank(pager.userSessionId)) {
cb.query().setUserSessionId_Term(pager.userSessionId);
}
if (StringUtil.isNotBlank(pager.accessType)) {
cb.query().setAccessType_Term(pager.accessType);
}
if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
String[] values = pager.requestedTimeRange.split(" - ");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
if (values.length > 0) {
cb.query().setRequestedAt_GreaterEqual(parseDateTime(values[0], formatter));
}
if (values.length > 1) {
cb.query().setRequestedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
}
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to parse " + pager.requestedTimeRange, e);
}
}
}
createSearchLogCondition(pager, cb);
});
}
@ -164,7 +304,94 @@ public class SearchLogService {
return list;
}
protected LocalDateTime parseDateTime(String value, DateTimeFormatter formatter) {
private void updatePagerByAgg(final SearchLogPager pager, final int size) {
pager.setAllPageCount(1);
pager.setAllRecordCount(size);
pager.setCurrentPageNumber(1);
pager.setExistNextPage(false);
pager.setExistPrePage(false);
pager.setPageSize(pager.getPageSize());
}
private void createSearchLogCondition(final SearchLogPager pager, final SearchLogCB cb) {
if (StringUtil.isNotBlank(pager.queryId)) {
cb.query().setQueryId_Term(pager.queryId);
}
if (StringUtil.isNotBlank(pager.userSessionId)) {
cb.query().setUserSessionId_Term(pager.userSessionId);
}
if (StringUtil.isNotBlank(pager.accessType)) {
cb.query().setAccessType_Term(pager.accessType);
}
if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
final String[] values = pager.requestedTimeRange.split(" - ");
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
if (values.length > 0) {
cb.query().setRequestedAt_GreaterEqual(parseDateTime(values[0], formatter));
}
if (values.length > 1) {
cb.query().setRequestedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
}
} catch (final Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to parse " + pager.requestedTimeRange, e);
}
}
}
}
private void createFavoriteLogCondition(final SearchLogPager pager, final FavoriteLogCB cb) {
if (StringUtil.isNotBlank(pager.queryId)) {
cb.query().setQueryId_Term(pager.queryId);
}
if (StringUtil.isNotBlank(pager.userSessionId)) {
cb.query().setUserInfoId_Term(pager.userSessionId);
}
if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
final String[] values = pager.requestedTimeRange.split(" - ");
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
if (values.length > 0) {
cb.query().setCreatedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
}
if (values.length > 1) {
cb.query().setCreatedAt_LessEqual(parseDateTime(values[1], formatter));
}
} catch (final Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to parse " + pager.requestedTimeRange, e);
}
}
}
}
private void createClickLogCondition(final SearchLogPager pager, final ClickLogCB cb) {
if (StringUtil.isNotBlank(pager.queryId)) {
cb.query().setQueryId_Term(pager.queryId);
}
if (StringUtil.isNotBlank(pager.userSessionId)) {
cb.query().setUserSessionId_Term(pager.userSessionId);
}
if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
final String[] values = pager.requestedTimeRange.split(" - ");
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
try {
if (values.length > 0) {
cb.query().setRequestedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
}
if (values.length > 1) {
cb.query().setRequestedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
}
} catch (final Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to parse " + pager.requestedTimeRange, e);
}
}
}
}
protected LocalDateTime parseDateTime(final String value, final DateTimeFormatter formatter) {
return LocalDateTime.parse(value, formatter).atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

View file

@ -69,4 +69,18 @@ public class EsSqlClause extends AbstractSqlClause {
protected String createSqlSuffix() {
return null;
}
@Override
public void fetchFirst(int fetchSize) {
_fetchScopeEffective = true;
if (fetchSize < 0) {
String msg = "Argument[fetchSize] should be plus: " + fetchSize;
throw new IllegalArgumentException(msg);
}
_fetchStartIndex = 0;
_fetchSize = fetchSize;
_fetchPageNumber = 1;
doClearFetchPageClause();
doFetchFirst();
}
}

View file

@ -69,4 +69,18 @@ public class EsSqlClause extends AbstractSqlClause {
protected String createSqlSuffix() {
return null;
}
@Override
public void fetchFirst(int fetchSize) {
_fetchScopeEffective = true;
if (fetchSize < 0) {
String msg = "Argument[fetchSize] should be plus: " + fetchSize;
throw new IllegalArgumentException(msg);
}
_fetchStartIndex = 0;
_fetchSize = fetchSize;
_fetchPageNumber = 1;
doClearFetchPageClause();
doFetchFirst();
}
}

View file

@ -69,4 +69,18 @@ public class EsSqlClause extends AbstractSqlClause {
protected String createSqlSuffix() {
return null;
}
@Override
public void fetchFirst(int fetchSize) {
_fetchScopeEffective = true;
if (fetchSize < 0) {
String msg = "Argument[fetchSize] should be plus: " + fetchSize;
throw new IllegalArgumentException(msg);
}
_fetchStartIndex = 0;
_fetchSize = fetchSize;
_fetchPageNumber = 1;
doClearFetchPageClause();
doFetchFirst();
}
}

View file

@ -2835,12 +2835,45 @@ public class FessLabels extends UserMessages {
/** The key of the message: Favorite Log */
public static final String LABELS_searchlog_log_type_favorite = "{labels.searchlog_log_type_favorite}";
/** The key of the message: Keywords */
public static final String LABELS_searchlog_log_type_search_keyword = "{labels.searchlog_log_type_search_keyword}";
/** The key of the message: Zero Hits */
public static final String LABELS_searchlog_log_type_search_zerohit = "{labels.searchlog_log_type_search_zerohit}";
/** The key of the message: Zero Clicks */
public static final String LABELS_searchlog_log_type_search_zeroclick = "{labels.searchlog_log_type_search_zeroclick}";
/** The key of the message: Keyword by Hour */
public static final String LABELS_searchlog_log_type_search_count_hour = "{labels.searchlog_log_type_search_count_hour}";
/** The key of the message: Keyword by Day */
public static final String LABELS_searchlog_log_type_search_count_day = "{labels.searchlog_log_type_search_count_day}";
/** The key of the message: User by Hour */
public static final String LABELS_searchlog_log_type_search_user_hour = "{labels.searchlog_log_type_search_user_hour}";
/** The key of the message: User by Day */
public static final String LABELS_searchlog_log_type_search_user_day = "{labels.searchlog_log_type_search_user_day}";
/** The key of the message: Request Time Avg. by Hour */
public static final String LABELS_searchlog_log_type_search_reqtimeavg_hour = "{labels.searchlog_log_type_search_reqtimeavg_hour}";
/** The key of the message: Request Time Avg. by Day */
public static final String LABELS_searchlog_log_type_search_reqtimeavg_day = "{labels.searchlog_log_type_search_reqtimeavg_day}";
/** The key of the message: Message */
public static final String LABELS_searchlog_log_message = "{labels.searchlog_log_message}";
/** The key of the message: Time */
public static final String LABELS_searchlog_requested_time = "{labels.searchlog_requested_time}";
/** The key of the message: Value */
public static final String LABELS_searchlog_value = "{labels.searchlog_value}";
/** The key of the message: Count */
public static final String LABELS_searchlog_count = "{labels.searchlog_count}";
/** The key of the message: Log Details */
public static final String LABELS_searchlog_configuration_details = "{labels.searchlog_configuration_details}";

View file

@ -936,8 +936,19 @@ labels.searchlog_log_type=Log Type
labels.searchlog_log_type_search=Search Log
labels.searchlog_log_type_click=Click Log
labels.searchlog_log_type_favorite=Favorite Log
labels.searchlog_log_type_search_keyword=Keywords
labels.searchlog_log_type_search_zerohit=Zero Hits
labels.searchlog_log_type_search_zeroclick=Zero Clicks
labels.searchlog_log_type_search_count_hour=Keyword by Hour
labels.searchlog_log_type_search_count_day=Keyword by Day
labels.searchlog_log_type_search_user_hour=User by Hour
labels.searchlog_log_type_search_user_day=User by Day
labels.searchlog_log_type_search_reqtimeavg_hour=Request Time Avg. by Hour
labels.searchlog_log_type_search_reqtimeavg_day=Request Time Avg. by Day
labels.searchlog_log_message=Message
labels.searchlog_requested_time=Time
labels.searchlog_value=Value
labels.searchlog_count=Count
labels.searchlog_configuration_details=Log Details
labels.searchlog_configuration_link_top=Search Log
labels.searchlog_configuration_link_details=Details

View file

@ -936,8 +936,19 @@ labels.searchlog_log_type=Log Type
labels.searchlog_log_type_search=Search Log
labels.searchlog_log_type_click=Click Log
labels.searchlog_log_type_favorite=Favorite Log
labels.searchlog_log_type_search_keyword=Keywords
labels.searchlog_log_type_search_zerohit=Zero Hits
labels.searchlog_log_type_search_zeroclick=Zero Clicks
labels.searchlog_log_type_search_count_hour=Keyword by Hour
labels.searchlog_log_type_search_count_day=Keyword by Day
labels.searchlog_log_type_search_user_hour=User by Hour
labels.searchlog_log_type_search_user_day=User by Day
labels.searchlog_log_type_search_reqtimeavg_hour=Request Time Avg. by Hour
labels.searchlog_log_type_search_reqtimeavg_day=Request Time Avg. by Day
labels.searchlog_log_message=Message
labels.searchlog_requested_time=Time
labels.searchlog_value=Value
labels.searchlog_count=Count
labels.searchlog_configuration_details=Log Details
labels.searchlog_configuration_link_top=Search Log
labels.searchlog_configuration_link_details=Details

View file

@ -936,8 +936,19 @@ labels.searchlog_log_type=ログ種別
labels.searchlog_log_type_search=検索ログ
labels.searchlog_log_type_click=クリックログ
labels.searchlog_log_type_favorite=お気に入りログ
labels.searchlog_log_type_search_keyword=キーワード数
labels.searchlog_log_type_search_zerohit=ゼロ件ヒット数
labels.searchlog_log_type_search_zeroclick=ゼロ件クリック数
labels.searchlog_log_type_search_count_hour=検索数/時
labels.searchlog_log_type_search_count_day=検索数/日
labels.searchlog_log_type_search_user_hour=ユーザー数/時
labels.searchlog_log_type_search_user_day=ユーザー数/日
labels.searchlog_log_type_search_reqtimeavg_hour=リクエスト平均時間/時
labels.searchlog_log_type_search_reqtimeavg_day=リクエスト平均時間/日
labels.searchlog_log_message=メッセージ
labels.searchlog_requested_time=時刻
labels.searchlog_value=
labels.searchlog_count=件数
labels.searchlog_configuration_details=ログ詳細
labels.searchlog_configuration_link_top=検索ログ
labels.searchlog_configuration_link_details=詳細

View file

@ -53,6 +53,14 @@
<la:option value="search"><la:message key="labels.searchlog_log_type_search" /></la:option>
<la:option value="click"><la:message key="labels.searchlog_log_type_click" /></la:option>
<la:option value="favorite"><la:message key="labels.searchlog_log_type_favorite" /></la:option>
<la:option value="search_count_hour_agg"><la:message key="labels.searchlog_log_type_search_count_hour" /></la:option>
<la:option value="search_count_day_agg"><la:message key="labels.searchlog_log_type_search_count_day" /></la:option>
<la:option value="search_user_hour_agg"><la:message key="labels.searchlog_log_type_search_user_hour" /></la:option>
<la:option value="search_user_day_agg"><la:message key="labels.searchlog_log_type_search_user_day" /></la:option>
<la:option value="search_reqtimeavg_hour_agg"><la:message key="labels.searchlog_log_type_search_reqtimeavg_hour" /></la:option>
<la:option value="search_reqtimeavg_day_agg"><la:message key="labels.searchlog_log_type_search_reqtimeavg_day" /></la:option>
<la:option value="search_keyword_agg"><la:message key="labels.searchlog_log_type_search_keyword" /></la:option>
<la:option value="search_zerohit_agg"><la:message key="labels.searchlog_log_type_search_zerohit" /></la:option>
</la:select>
</div>
</div>
@ -116,20 +124,48 @@
<table class="table table-bordered table-striped dataTable">
<thead>
<tr>
<c:if test="${!logType.endsWith('_agg')}">
<th class="col-sm-3"><la:message
key="labels.searchlog_requested_time" /></th>
<th><la:message
key="labels.searchlog_log_message" /></th>
</c:if>
<c:if test="${logType.startsWith('search_count_') or logType.startsWith('search_user_')}">
<th><la:message
key="labels.searchlog_requested_time" /></th>
<th class="col-sm-3"><la:message
key="labels.searchlog_count" /></th>
</c:if>
<c:if test="${logType.startsWith('search_reqtimeavg_')}">
<th><la:message
key="labels.searchlog_requested_time" /></th>
<th class="col-sm-3"><la:message
key="labels.searchlog_value" /></th>
</c:if>
<c:if test="${logType.startsWith('search_keyword_') or logType.startsWith('search_zerohit_')}">
<th><la:message
key="labels.searchlog_value" /></th>
<th class="col-sm-3"><la:message
key="labels.searchlog_count" /></th>
</c:if>
</tr>
</thead>
<tbody>
<c:forEach var="data" varStatus="s"
items="${searchLogItems}">
<c:if test="${!logType.endsWith('_agg')}">
<tr
data-href="${contextPath}/admin/searchlog/details/4/${f:u(logType)}/${f:u(data.id)}">
<td>${f:h(data.requestedAt)}</td>
<td>${f:h(data.logMessage)}</td>
</tr>
</c:if>
<c:if test="${logType.endsWith('_agg')}">
<tr>
<td>${f:h(data.key)}</td>
<td>${f:h(data.count)}</td>
</tr>
</c:if>
</c:forEach>
</tbody>
</table>