fix #1873 add aggregations for search logs
This commit is contained in:
parent
eae48aba61
commit
31f64e09e8
10 changed files with 468 additions and 77 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}";
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=詳細
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue