fix #1985 add screen_width parameter

This commit is contained in:
Shinsuke Sugaya 2019-01-24 12:24:46 +09:00
parent c010e0aed1
commit 197d95b6a6
11 changed files with 183 additions and 42 deletions

View file

@ -49,6 +49,7 @@ import org.codelibs.fess.api.WebApiRequest;
import org.codelibs.fess.app.service.SearchService;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.SearchRenderData;
import org.codelibs.fess.entity.SearchRequestParams;
import org.codelibs.fess.exception.InvalidAccessTokenException;
@ -433,7 +434,7 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
}
}
protected static class GsaRequestParams implements SearchRequestParams {
protected static class GsaRequestParams extends SearchRequestParams {
private final HttpServletRequest request;
@ -622,6 +623,10 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
return request.getParameter("sdh");
}
@Override
public HighlightInfo getHighlightInfo() {
return ComponentUtil.getViewHelper().createHighlightInfo();
}
}
public void setGsaPathPrefix(final String gsaPathPrefix) {

View file

@ -40,6 +40,7 @@ import org.codelibs.fess.app.service.FavoriteLogService;
import org.codelibs.fess.app.service.SearchService;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.PingResponse;
import org.codelibs.fess.entity.SearchRenderData;
import org.codelibs.fess.entity.SearchRequestParams;
@ -674,7 +675,7 @@ public class JsonApiManager extends BaseJsonApiManager {
}
protected static class JsonRequestParams implements SearchRequestParams {
protected static class JsonRequestParams extends SearchRequestParams {
private final HttpServletRequest request;
@ -806,5 +807,9 @@ public class JsonApiManager extends BaseJsonApiManager {
return request.getParameter("sdh");
}
@Override
public HighlightInfo getHighlightInfo() {
return ComponentUtil.getViewHelper().createHighlightInfo();
}
}
}

View file

@ -35,6 +35,7 @@ import org.codelibs.fess.api.BaseJsonApiManager;
import org.codelibs.fess.app.service.SearchService;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.SearchRequestParams;
import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
import org.codelibs.fess.exception.InvalidAccessTokenException;
@ -163,7 +164,7 @@ public class SuggestApiManager extends BaseJsonApiManager {
writeJsonResponse(status, buf.toString(), errMsg);
}
protected static class RequestParameter implements SearchRequestParams {
protected static class RequestParameter extends SearchRequestParams {
private final String query;
private final String[] fields;
@ -293,5 +294,10 @@ public class SuggestApiManager extends BaseJsonApiManager {
public String getSimilarDocHash() {
throw new UnsupportedOperationException();
}
@Override
public HighlightInfo getHighlightInfo() {
return new HighlightInfo();
}
}
}

View file

@ -111,13 +111,11 @@ public class SearchService {
query = ComponentUtil.getQueryStringBuilder().params(params).build() + " sort:" + sortField;
}
final List<Map<String, Object>> documentItems =
fessEsClient.search(
fessConfig.getIndexDocumentSearchIndex(),
fessConfig.getIndexDocumentType(),
fessEsClient.search(fessConfig.getIndexDocumentSearchIndex(), fessConfig.getIndexDocumentType(),
searchRequestBuilder -> {
queryHelper.processSearchPreference(searchRequestBuilder, userBean, query);
return SearchConditionBuilder.builder(searchRequestBuilder).query(query).offset(pageStart).size(pageSize)
.facetInfo(params.getFacetInfo()).geoInfo(params.getGeoInfo())
.facetInfo(params.getFacetInfo()).geoInfo(params.getGeoInfo()).highlightInfo(params.getHighlightInfo())
.similarDocHash(params.getSimilarDocHash()).responseFields(queryHelper.getResponseFields())
.searchRequestType(params.getType()).build();
}, (searchRequestBuilder, execTime, searchResponse) -> {

View file

@ -26,6 +26,7 @@ import javax.validation.constraints.Size;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.SearchRequestParams;
import org.codelibs.fess.mylasta.direction.FessConfig;
import org.codelibs.fess.util.ComponentUtil;
@ -36,7 +37,7 @@ import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
* @author shinsuke
* @author Keiichi Watanabe
*/
public class ListForm implements SearchRequestParams {
public class ListForm extends SearchRequestParams {
@Size(max = 1000)
public String q;
@ -117,6 +118,11 @@ public class ListForm implements SearchRequestParams {
return null;
}
@Override
public HighlightInfo getHighlightInfo() {
return new HighlightInfo();
}
@Override
public String getSort() {
return sort;

View file

@ -26,13 +26,14 @@ import javax.validation.constraints.Size;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.SearchRequestParams;
import org.codelibs.fess.mylasta.direction.FessConfig;
import org.codelibs.fess.util.ComponentUtil;
import org.lastaflute.web.util.LaRequestUtil;
import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
public class SearchForm implements SearchRequestParams {
public class SearchForm extends SearchRequestParams {
public Map<String, String[]> fields = new HashMap<>();
@ -122,6 +123,11 @@ public class SearchForm implements SearchRequestParams {
return ComponentUtil.getQueryHelper().getDefaultFacetInfo();
}
@Override
public HighlightInfo getHighlightInfo() {
return ComponentUtil.getViewHelper().createHighlightInfo();
}
@Override
public String getSort() {
return sort;

View file

@ -0,0 +1,59 @@
/*
* Copyright 2012-2019 CodeLibs Project and the Others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.codelibs.fess.entity;
import org.codelibs.fess.mylasta.direction.FessConfig;
import org.codelibs.fess.util.ComponentUtil;
public class HighlightInfo {
private String type;
private int fragmentSize;
private int numOfFragments;
public HighlightInfo() {
FessConfig fessConfig = ComponentUtil.getFessConfig();
this.type = fessConfig.getQueryHighlightType();
this.fragmentSize = fessConfig.getQueryHighlightFragmentSizeAsInteger();
this.numOfFragments = fessConfig.getQueryHighlightNumberOfFragmentsAsInteger();
}
public String getType() {
return type;
}
public HighlightInfo type(String type) {
this.type = type;
return this;
}
public int getFragmentSize() {
return fragmentSize;
}
public HighlightInfo fragmentSize(int fragmentSize) {
this.fragmentSize = fragmentSize;
return this;
}
public int getNumOfFragments() {
return numOfFragments;
}
public HighlightInfo numOfFragments(int numOfFragments) {
this.numOfFragments = numOfFragments;
return this;
}
}

View file

@ -24,53 +24,55 @@ import javax.servlet.http.HttpServletRequest;
import org.codelibs.core.lang.StringUtil;
public interface SearchRequestParams {
public abstract class SearchRequestParams {
String AS_NQ = "nq";
public static final String AS_NQ = "nq";
String AS_OQ = "oq";
public static final String AS_OQ = "oq";
String AS_EPQ = "epq";
public static final String AS_EPQ = "epq";
String AS_Q = "q";
public static final String AS_Q = "q";
String AS_FILETYPE = "filetype";
public static final String AS_FILETYPE = "filetype";
String AS_SITESEARCH = "sitesearch";
public static final String AS_SITESEARCH = "sitesearch";
String AS_OCCURRENCE = "occt";
public static final String AS_OCCURRENCE = "occt";
String AS_TIMESTAMP = "timestamp";
public static final String AS_TIMESTAMP = "timestamp";
String getQuery();
public abstract String getQuery();
Map<String, String[]> getFields();
public abstract Map<String, String[]> getFields();
Map<String, String[]> getConditions();
public abstract Map<String, String[]> getConditions();
String[] getLanguages();
public abstract String[] getLanguages();
GeoInfo getGeoInfo();
public abstract GeoInfo getGeoInfo();
FacetInfo getFacetInfo();
public abstract FacetInfo getFacetInfo();
String getSort();
public abstract HighlightInfo getHighlightInfo();
int getStartPosition();
public abstract String getSort();
int getPageSize();
public abstract int getStartPosition();
String[] getExtraQueries();
public abstract int getPageSize();
Object getAttribute(String name);
public abstract String[] getExtraQueries();
Locale getLocale();
public abstract Object getAttribute(String name);
SearchRequestType getType();
public abstract Locale getLocale();
String getSimilarDocHash();
public abstract SearchRequestType getType();
default boolean hasConditionQuery() {
public abstract String getSimilarDocHash();
public boolean hasConditionQuery() {
final Map<String, String[]> conditions = getConditions();
return !isEmptyArray(conditions.get(AS_Q))//
|| !isEmptyArray(conditions.get(AS_EPQ))//
@ -81,22 +83,22 @@ public interface SearchRequestParams {
|| !isEmptyArray(conditions.get(AS_FILETYPE));
}
default boolean isEmptyArray(final String[] values) {
protected boolean isEmptyArray(final String[] values) {
if (values == null || values.length == 0) {
return true;
}
return stream(values).get(stream -> stream.allMatch(StringUtil::isBlank));
}
default String[] simplifyArray(final String[] values) {
protected String[] simplifyArray(final String[] values) {
return stream(values).get(stream -> stream.filter(StringUtil::isNotBlank).distinct().toArray(n -> new String[n]));
}
default String[] getParamValueArray(final HttpServletRequest request, final String param) {
protected String[] getParamValueArray(final HttpServletRequest request, final String param) {
return simplifyArray(request.getParameterValues(param));
}
default FacetInfo createFacetInfo(final HttpServletRequest request) {
protected FacetInfo createFacetInfo(final HttpServletRequest request) {
final String[] fields = getParamValueArray(request, "facet.field");
final String[] queries = getParamValueArray(request, "facet.query");
if (fields.length == 0 && queries.length == 0) {
@ -124,7 +126,7 @@ public interface SearchRequestParams {
return facetInfo;
}
default GeoInfo createGeoInfo(final HttpServletRequest request) {
protected GeoInfo createGeoInfo(final HttpServletRequest request) {
return new GeoInfo(request);
}

View file

@ -51,6 +51,7 @@ import org.codelibs.elasticsearch.runner.ElasticsearchClusterRunner.Configs;
import org.codelibs.fess.Constants;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.PingResponse;
import org.codelibs.fess.entity.QueryContext;
import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
@ -942,6 +943,7 @@ public class FessEsClient implements Client {
private int size = Constants.DEFAULT_PAGE_SIZE;
private GeoInfo geoInfo;
private FacetInfo facetInfo;
private HighlightInfo highlightInfo;
private String similarDocHash;
private SearchRequestType searchRequestType = SearchRequestType.SEARCH;
private boolean isScroll = false;
@ -960,8 +962,9 @@ public class FessEsClient implements Client {
params.put("responseFields", responseFields);
params.put("offset", offset);
params.put("size", size);
// params.put("geoInfo", geoInfo);
// params.put("facetInfo", facetInfo);
// TODO support rescorer(convert to map)
// params.put("geoInfo", geoInfo);
// params.put("facetInfo", facetInfo);
params.put("similarDocHash", similarDocHash);
return params;
}
@ -996,6 +999,11 @@ public class FessEsClient implements Client {
return this;
}
public SearchConditionBuilder highlightInfo(final HighlightInfo highlightInfo) {
this.highlightInfo = highlightInfo;
return this;
}
public SearchConditionBuilder similarDocHash(final String similarDocHash) {
if (StringUtil.isNotBlank(similarDocHash)) {
this.similarDocHash = similarDocHash;
@ -1059,8 +1067,8 @@ public class FessEsClient implements Client {
// highlighting
final HighlightBuilder highlightBuilder = new HighlightBuilder();
queryHelper.highlightedFields(stream -> stream.forEach(hf -> highlightBuilder.field(new HighlightBuilder.Field(hf)
.highlighterType(fessConfig.getQueryHighlightType()).fragmentSize(fessConfig.getQueryHighlightFragmentSizeAsInteger())
.numOfFragments(fessConfig.getQueryHighlightNumberOfFragmentsAsInteger()))));
.highlighterType(highlightInfo.getType()).fragmentSize(highlightInfo.getFragmentSize())
.numOfFragments(highlightInfo.getNumOfFragments()))));
searchRequestBuilder.highlighter(highlightBuilder);
// facets

View file

@ -39,6 +39,7 @@ import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.commons.lang3.StringUtils;
@ -54,6 +55,7 @@ import org.codelibs.fess.crawler.client.CrawlerClientFactory;
import org.codelibs.fess.crawler.entity.ResponseData;
import org.codelibs.fess.crawler.util.CharUtil;
import org.codelibs.fess.entity.FacetQueryView;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.es.config.exentity.CrawlingConfig;
import org.codelibs.fess.exception.FessSystemException;
import org.codelibs.fess.helper.UserAgentHelper.UserAgentType;
@ -82,6 +84,10 @@ public class ViewHelper {
private static final Logger logger = LoggerFactory.getLogger(ViewHelper.class);
protected static final String SCREEN_WIDTH = "screen_width";
protected static final int TABLET_WIDTH = 768;
protected static final String CONTENT_DISPOSITION = "Content-Disposition";
protected static final String HL_CACHE = "hl_cache";
@ -210,6 +216,40 @@ public class ViewHelper {
return str.replaceAll(originalHighlightTagPre, StringUtil.EMPTY).replaceAll(originalHighlightTagPost, StringUtil.EMPTY);
}
public HighlightInfo createHighlightInfo() {
return LaRequestUtil.getOptionalRequest().map(req -> {
final HighlightInfo highlightInfo = new HighlightInfo();
final String widthStr = req.getParameter(SCREEN_WIDTH);
if (StringUtil.isNotBlank(widthStr)) {
final int width = Integer.parseInt(widthStr);
updateHighlisthInfo(highlightInfo, width);
final HttpSession session = req.getSession(false);
if (session != null) {
session.setAttribute(SCREEN_WIDTH, width);
}
} else {
final HttpSession session = req.getSession(false);
if (session != null) {
final Integer width = (Integer) session.getAttribute(SCREEN_WIDTH);
if (width != null) {
updateHighlisthInfo(highlightInfo, width);
}
}
}
return highlightInfo;
}).orElse(new HighlightInfo());
}
protected void updateHighlisthInfo(final HighlightInfo highlightInfo, final int width) {
if (width < TABLET_WIDTH) {
float ratio = ((float) width) / ((float) TABLET_WIDTH);
if (ratio < 0.5) {
ratio = 0.5f;
}
highlightInfo.fragmentSize((int) (highlightInfo.getFragmentSize() * ratio));
}
}
public String getUrlLink(final Map<String, Object> document) {
final FessConfig fessConfig = ComponentUtil.getFessConfig();
String url = DocumentUtil.getValue(document, fessConfig.getIndexFieldUrl(), String.class);

View file

@ -21,6 +21,7 @@ import java.util.Map;
import org.codelibs.fess.entity.FacetInfo;
import org.codelibs.fess.entity.GeoInfo;
import org.codelibs.fess.entity.HighlightInfo;
import org.codelibs.fess.entity.SearchRequestParams;
import org.codelibs.fess.unit.UnitFessTestCase;
@ -150,6 +151,11 @@ public class QueryStringBuilderTest extends UnitFessTestCase {
return null;
}
@Override
public HighlightInfo getHighlightInfo() {
return new HighlightInfo();
}
}).build();
}
}