refactoring for query helper
This commit is contained in:
parent
bdee8570ba
commit
e8ced1368c
22 changed files with 2367 additions and 1273 deletions
2
pom.xml
2
pom.xml
|
@ -53,7 +53,7 @@
|
|||
<commons.fileupload.version>1.3.1</commons.fileupload.version>
|
||||
|
||||
<!-- Testing -->
|
||||
<junit.version>4.8.2</junit.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<utflute.version>0.5.2</utflute.version>
|
||||
|
||||
<!-- Crawler -->
|
||||
|
|
|
@ -46,10 +46,6 @@ public class Constants extends CoreLibConstants {
|
|||
|
||||
public static final String ON = "on";
|
||||
|
||||
public static final String ASC = "asc";
|
||||
|
||||
public static final String DESC = "desc";
|
||||
|
||||
public static final String READY = "ready";
|
||||
|
||||
public static final String RUNNING = "running";
|
||||
|
|
|
@ -61,7 +61,7 @@ public class FessBoot extends TomcatBoot {
|
|||
}
|
||||
|
||||
final String tomcatConfigPath = getTomcatConfigPath();
|
||||
TomcatBoot tomcatBoot = new FessBoot(getPort(), getContextPath()) //
|
||||
final TomcatBoot tomcatBoot = new FessBoot(getPort(), getContextPath()) //
|
||||
.useTldDetect(); // for JSP
|
||||
if (tomcatConfigPath != null) {
|
||||
tomcatBoot.configure(tomcatConfigPath); // e.g. URIEncoding
|
||||
|
|
|
@ -19,14 +19,15 @@ public class SuggestApiManager extends BaseApiManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
public boolean matches(final HttpServletRequest request) {
|
||||
return false; // TODO remove
|
||||
// final String servletPath = request.getServletPath();
|
||||
// return servletPath.startsWith(pathPrefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
public void process(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException,
|
||||
ServletException {
|
||||
throw new UnsupportedOperationException("TODO");
|
||||
}
|
||||
|
||||
|
|
|
@ -128,12 +128,13 @@ public class SearchService {
|
|||
final QueryResponseList queryResponseList = (QueryResponseList) documentItems;
|
||||
data.setFacetResponse(queryResponseList.getFacetResponse());
|
||||
|
||||
final String[] highlightQueries = (String[]) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
|
||||
@SuppressWarnings("unchecked")
|
||||
final Set<String> highlightQueries = (Set<String>) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
|
||||
if (highlightQueries != null) {
|
||||
final StringBuilder buf = new StringBuilder(100);
|
||||
for (final String q : highlightQueries) {
|
||||
highlightQueries.stream().forEach(q -> {
|
||||
buf.append("&hq=").append(q);
|
||||
}
|
||||
});
|
||||
data.setAppendHighlightParams(buf.toString());
|
||||
}
|
||||
|
||||
|
@ -325,11 +326,11 @@ public class SearchService {
|
|||
return fessEsClient.update(fieldHelper.docIndex, fieldHelper.docType, id, field, value);
|
||||
}
|
||||
|
||||
public boolean bulkUpdate(Consumer<BulkRequestBuilder> consumer) {
|
||||
BulkRequestBuilder builder = fessEsClient.prepareBulk();
|
||||
public boolean bulkUpdate(final Consumer<BulkRequestBuilder> consumer) {
|
||||
final BulkRequestBuilder builder = fessEsClient.prepareBulk();
|
||||
consumer.accept(builder);
|
||||
try {
|
||||
BulkResponse response = builder.execute().get();
|
||||
final BulkResponse response = builder.execute().get();
|
||||
if (response.hasFailures()) {
|
||||
throw new FessEsClientException(response.buildFailureMessage());
|
||||
} else {
|
||||
|
|
|
@ -126,7 +126,7 @@ public class AdminCrawlingsessionAction extends FessAdminAction {
|
|||
public HtmlResponse deletefromconfirm(final EditForm form) {
|
||||
form.crudMode = CrudMode.DELETE;
|
||||
validate(form, messages -> {}, toIndexHtml());
|
||||
String id = form.id;
|
||||
final String id = form.id;
|
||||
crawlingSessionService.getCrawlingSession(id).ifPresent(entity -> {
|
||||
copyBeanToBean(entity, form, op -> {});
|
||||
}).orElse(() -> {
|
||||
|
@ -166,7 +166,7 @@ public class AdminCrawlingsessionAction extends FessAdminAction {
|
|||
public HtmlResponse delete(final EditForm form) {
|
||||
verifyCrudMode(form.crudMode, CrudMode.DELETE);
|
||||
validate(form, messages -> {}, toIndexHtml());
|
||||
String id = form.id;
|
||||
final String id = form.id;
|
||||
crawlingSessionService.getCrawlingSession(id).alwaysPresent(entity -> {
|
||||
crawlingSessionService.delete(entity);
|
||||
saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
|
||||
|
|
|
@ -100,6 +100,7 @@ public abstract class FessAdminAction extends FessBaseAction {
|
|||
@Override
|
||||
protected TypicalEmbeddedKeySupplier newTypicalEmbeddedKeySupplier() {
|
||||
return new TypicalSimpleEmbeddedKeySupplier() {
|
||||
@Override
|
||||
public String getErrorMessageForwardPath() {
|
||||
return "/admin/error/error.jsp";
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ public abstract class FessSearchAction extends FessBaseAction {
|
|||
@Override
|
||||
protected TypicalEmbeddedKeySupplier newTypicalEmbeddedKeySupplier() {
|
||||
return new TypicalSimpleEmbeddedKeySupplier() {
|
||||
@Override
|
||||
public String getErrorMessageForwardPath() {
|
||||
return "/error/system.jsp";
|
||||
}
|
||||
|
|
108
src/main/java/org/codelibs/fess/entity/QueryContext.java
Normal file
108
src/main/java/org/codelibs/fess/entity/QueryContext.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright 2009-2015 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 org.codelibs.fess.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.FilterBuilder;
|
||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
|
||||
public class QueryContext {
|
||||
private QueryBuilder queryBuilder;
|
||||
|
||||
private final List<SortBuilder> sortBuilderList = new ArrayList<>();
|
||||
|
||||
private final String queryString;
|
||||
|
||||
private final Set<String> highlightedQuerySet = new HashSet<>();
|
||||
|
||||
private final Map<String, List<String>> fieldLogMap = new HashMap<>();
|
||||
|
||||
public QueryContext(final String queryString) {
|
||||
this.queryString = queryString;
|
||||
LaRequestUtil.getOptionalRequest().ifPresent(request -> {
|
||||
request.setAttribute(Constants.HIGHLIGHT_QUERIES, highlightedQuerySet);
|
||||
request.setAttribute(Constants.FIELD_LOGS, fieldLogMap);
|
||||
});
|
||||
}
|
||||
|
||||
public void addFilter(final FilterBuilder filterBuilder) {
|
||||
queryBuilder = QueryBuilders.filteredQuery(queryBuilder, filterBuilder);
|
||||
}
|
||||
|
||||
public void addQuery(final Consumer<BoolQueryBuilder> boolQuery) {
|
||||
BoolQueryBuilder builder;
|
||||
if (queryBuilder instanceof BoolQueryBuilder) {
|
||||
builder = (BoolQueryBuilder) queryBuilder;
|
||||
} else if (queryBuilder instanceof MatchAllQueryBuilder) {
|
||||
builder = QueryBuilders.boolQuery();
|
||||
} else {
|
||||
builder = QueryBuilders.boolQuery().must(queryBuilder);
|
||||
}
|
||||
boolQuery.accept(builder);
|
||||
if (builder.hasClauses()) {
|
||||
queryBuilder = builder;
|
||||
}
|
||||
}
|
||||
|
||||
public void setQueryBuilder(final QueryBuilder queryBuilder) {
|
||||
this.queryBuilder = queryBuilder;
|
||||
}
|
||||
|
||||
public void addSorts(final SortBuilder... sortBuilders) {
|
||||
Stream.of(sortBuilders).forEach(sortBuilder -> sortBuilderList.add(sortBuilder));
|
||||
}
|
||||
|
||||
public boolean hasSorts() {
|
||||
return !sortBuilderList.isEmpty();
|
||||
}
|
||||
|
||||
public List<SortBuilder> sortBuilders() {
|
||||
return sortBuilderList;
|
||||
}
|
||||
|
||||
public QueryBuilder getQueryBuilder() {
|
||||
return queryBuilder;
|
||||
}
|
||||
|
||||
public void addFieldLog(String field, String text) {
|
||||
List<String> list = fieldLogMap.get(field);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
fieldLogMap.put(field, list);
|
||||
}
|
||||
list.add(text);
|
||||
}
|
||||
|
||||
public void addHighlightedQuery(String text) {
|
||||
highlightedQuerySet.add(text);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009-2015 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 org.codelibs.fess.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
|
||||
public class SearchQuery {
|
||||
private String query;
|
||||
|
||||
private final List<String> filterQueryList = new ArrayList<String>();
|
||||
|
||||
private final List<SortField> sortFieldList = new ArrayList<SortField>();
|
||||
|
||||
private String minimumShouldMatch;
|
||||
|
||||
private String defType;
|
||||
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(final String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public SearchQuery query(final String query) {
|
||||
setQuery(query);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean queryExists() {
|
||||
return StringUtil.isNotBlank(query);
|
||||
}
|
||||
|
||||
public void addSortField(final String field, final String order) {
|
||||
if (StringUtil.isNotBlank(field) && (Constants.ASC.equals(order) || Constants.DESC.equals(order))) {
|
||||
final SortField sortField = new SortField();
|
||||
sortField.setField(field);
|
||||
sortField.setOrder(order);
|
||||
sortFieldList.add(sortField);
|
||||
}
|
||||
}
|
||||
|
||||
public SearchQuery sortField(final String field, final String order) {
|
||||
addSortField(field, order);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SortField[] getSortFields() {
|
||||
return sortFieldList.toArray(new SortField[sortFieldList.size()]);
|
||||
}
|
||||
|
||||
public void addFilterQuery(final String fq) {
|
||||
filterQueryList.add(fq);
|
||||
}
|
||||
|
||||
public boolean hasFilterQueries() {
|
||||
return !filterQueryList.isEmpty();
|
||||
}
|
||||
|
||||
public String[] getFilterQueries() {
|
||||
return filterQueryList.toArray(new String[filterQueryList.size()]);
|
||||
}
|
||||
|
||||
public String getMinimumShouldMatch() {
|
||||
return minimumShouldMatch;
|
||||
}
|
||||
|
||||
public void setMinimumShouldMatch(final String minimumShouldMatch) {
|
||||
this.minimumShouldMatch = minimumShouldMatch;
|
||||
}
|
||||
|
||||
public String getDefType() {
|
||||
return defType;
|
||||
}
|
||||
|
||||
public void setDefType(final String defType) {
|
||||
this.defType = defType;
|
||||
}
|
||||
|
||||
public static class SortField {
|
||||
private String field;
|
||||
|
||||
private String order;
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setField(final String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(final String order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SortField [field=" + field + ", order=" + order + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SearchQuery [query=" + query + ", filterQueryList=" + filterQueryList + ", sortFieldList=" + sortFieldList
|
||||
+ ", minimumShouldMatch=" + minimumShouldMatch + "]";
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package org.codelibs.fess.es.client;
|
|||
import static org.codelibs.elasticsearch.runner.ElasticsearchClusterRunner.newConfigs;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -29,12 +30,12 @@ import org.codelibs.fess.Constants;
|
|||
import org.codelibs.fess.entity.FacetInfo;
|
||||
import org.codelibs.fess.entity.GeoInfo;
|
||||
import org.codelibs.fess.entity.PingResponse;
|
||||
import org.codelibs.fess.entity.SearchQuery;
|
||||
import org.codelibs.fess.entity.SearchQuery.SortField;
|
||||
import org.codelibs.fess.entity.QueryContext;
|
||||
import org.codelibs.fess.exception.ResultOffsetExceededException;
|
||||
import org.codelibs.fess.helper.QueryHelper;
|
||||
import org.codelibs.fess.indexer.FessSearchQueryException;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.StreamUtil;
|
||||
import org.dbflute.optional.OptionalEntity;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.action.Action;
|
||||
|
@ -134,10 +135,8 @@ import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
|||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.index.get.GetField;
|
||||
import org.elasticsearch.index.query.BoolFilterBuilder;
|
||||
import org.elasticsearch.index.query.FilterBuilders;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.indices.IndexAlreadyExistsException;
|
||||
import org.elasticsearch.indices.IndexMissingException;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
|
@ -145,9 +144,6 @@ import org.elasticsearch.search.SearchHitField;
|
|||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
|
||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -670,7 +666,6 @@ public class FessEsClient implements Client {
|
|||
public static class SearchConditionBuilder {
|
||||
private final SearchRequestBuilder searchRequestBuilder;
|
||||
private String query;
|
||||
private boolean administrativeAccess = false;
|
||||
private String[] responseFields;
|
||||
private int offset = Constants.DEFAULT_START_COUNT;
|
||||
private int size = Constants.DEFAULT_PAGE_SIZE;
|
||||
|
@ -691,7 +686,6 @@ public class FessEsClient implements Client {
|
|||
}
|
||||
|
||||
public SearchConditionBuilder administrativeAccess() {
|
||||
this.administrativeAccess = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -721,15 +715,22 @@ public class FessEsClient implements Client {
|
|||
}
|
||||
|
||||
public boolean build() {
|
||||
if (offset > ComponentUtil.getQueryHelper().getMaxSearchResultOffset()) {
|
||||
if (StringUtil.isBlank(query)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
|
||||
|
||||
if (offset > queryHelper.getMaxSearchResultOffset()) {
|
||||
throw new ResultOffsetExceededException("The number of result size is exceeded.");
|
||||
}
|
||||
|
||||
final SearchQuery searchQuery = ComponentUtil.getQueryHelper().build(query, administrativeAccess);
|
||||
final String q = searchQuery.getQuery();
|
||||
if (StringUtil.isBlank(q)) {
|
||||
return false;
|
||||
}
|
||||
final QueryContext queryContext = queryHelper.build(query, context -> {
|
||||
// geo
|
||||
if (geoInfo != null && geoInfo.isAvailable()) {
|
||||
context.addFilter(geoInfo.toFilterBuilder());
|
||||
}
|
||||
});
|
||||
|
||||
searchRequestBuilder.setFrom(offset).setSize(size);
|
||||
|
||||
|
@ -738,102 +739,49 @@ public class FessEsClient implements Client {
|
|||
}
|
||||
|
||||
// sort
|
||||
final SortField[] sortFields = searchQuery.getSortFields();
|
||||
if (sortFields.length != 0) {
|
||||
for (final SortField sortField : sortFields) {
|
||||
final FieldSortBuilder fieldSort = SortBuilders.fieldSort(sortField.getField());
|
||||
if (Constants.DESC.equals(sortField.getOrder())) {
|
||||
fieldSort.order(SortOrder.DESC);
|
||||
} else {
|
||||
fieldSort.order(SortOrder.ASC);
|
||||
}
|
||||
searchRequestBuilder.addSort(fieldSort);
|
||||
}
|
||||
} else if (ComponentUtil.getQueryHelper().hasDefaultSortFields()) {
|
||||
for (final SortField sortField : ComponentUtil.getQueryHelper().getDefaultSortFields()) {
|
||||
final FieldSortBuilder fieldSort = SortBuilders.fieldSort(sortField.getField());
|
||||
if (Constants.DESC.equals(sortField.getOrder())) {
|
||||
fieldSort.order(SortOrder.DESC);
|
||||
} else {
|
||||
fieldSort.order(SortOrder.ASC);
|
||||
}
|
||||
searchRequestBuilder.addSort(fieldSort);
|
||||
}
|
||||
}
|
||||
queryContext.sortBuilders().forEach(sortBuilder -> searchRequestBuilder.addSort(sortBuilder));
|
||||
|
||||
// highlighting
|
||||
if (ComponentUtil.getQueryHelper().getHighlightedFields() != null
|
||||
&& ComponentUtil.getQueryHelper().getHighlightedFields().length != 0) {
|
||||
for (final String hf : ComponentUtil.getQueryHelper().getHighlightedFields()) {
|
||||
searchRequestBuilder.addHighlightedField(hf, ComponentUtil.getQueryHelper().getHighlightFragmentSize());
|
||||
}
|
||||
}
|
||||
queryHelper.highlightedFields().forEach(
|
||||
hf -> searchRequestBuilder.addHighlightedField(hf, queryHelper.getHighlightFragmentSize()));
|
||||
|
||||
// facets
|
||||
if (facetInfo != null) {
|
||||
if (facetInfo.field != null) {
|
||||
for (final String f : facetInfo.field) {
|
||||
if (ComponentUtil.getQueryHelper().isFacetField(f)) {
|
||||
final String encodedField = BaseEncoding.base64().encode(f.getBytes(Charsets.UTF_8));
|
||||
final TermsBuilder termsBuilder =
|
||||
AggregationBuilders.terms(Constants.FACET_FIELD_PREFIX + encodedField).field(f);
|
||||
// TODO order
|
||||
if (facetInfo.limit != null) {
|
||||
// TODO
|
||||
termsBuilder.size(Integer.parseInt(facetInfo.limit));
|
||||
}
|
||||
searchRequestBuilder.addAggregation(termsBuilder);
|
||||
} else {
|
||||
throw new FessSearchQueryException("Invalid facet field: " + f);
|
||||
StreamUtil.of(facetInfo.field).forEach(f -> {
|
||||
if (queryHelper.isFacetField(f)) {
|
||||
final String encodedField = BaseEncoding.base64().encode(f.getBytes(Charsets.UTF_8));
|
||||
final TermsBuilder termsBuilder = AggregationBuilders.terms(Constants.FACET_FIELD_PREFIX + encodedField).field(f);
|
||||
// TODO order
|
||||
if (facetInfo.limit != null) {
|
||||
// TODO
|
||||
termsBuilder.size(Integer.parseInt(facetInfo.limit));
|
||||
}
|
||||
searchRequestBuilder.addAggregation(termsBuilder);
|
||||
} else {
|
||||
throw new FessSearchQueryException("Invalid facet field: " + f);
|
||||
}
|
||||
}
|
||||
if (facetInfo.query != null) {
|
||||
for (final String fq : facetInfo.query) {
|
||||
final String facetQuery = ComponentUtil.getQueryHelper().buildFacetQuery(fq);
|
||||
if (StringUtil.isNotBlank(facetQuery)) {
|
||||
final String encodedFacetQuery = BaseEncoding.base64().encode(facetQuery.getBytes(Charsets.UTF_8));
|
||||
final FilterAggregationBuilder filterBuilder =
|
||||
AggregationBuilders.filter(Constants.FACET_QUERY_PREFIX + encodedFacetQuery).filter(
|
||||
FilterBuilders.queryFilter(QueryBuilders.queryStringQuery(facetQuery)));
|
||||
// TODO order
|
||||
if (facetInfo.limit != null) {
|
||||
// TODO
|
||||
// filterBuilder.size(Integer.parseInt(facetInfo .limit));
|
||||
});
|
||||
StreamUtil.of(facetInfo.query).forEach(
|
||||
fq -> {
|
||||
final QueryContext facetContext = queryHelper.buildBaseQuery(fq, c -> {});
|
||||
if (facetContext != null) {
|
||||
final String encodedFacetQuery = BaseEncoding.base64().encode(fq.getBytes(StandardCharsets.UTF_8));
|
||||
final FilterAggregationBuilder filterBuilder =
|
||||
AggregationBuilders.filter(Constants.FACET_QUERY_PREFIX + encodedFacetQuery).filter(
|
||||
FilterBuilders.queryFilter(facetContext.getQueryBuilder()));
|
||||
// TODO order
|
||||
if (facetInfo.limit != null) {
|
||||
// TODO
|
||||
// filterBuilder.size(Integer.parseInt(facetInfo .limit));
|
||||
}
|
||||
searchRequestBuilder.addAggregation(filterBuilder);
|
||||
} else {
|
||||
throw new FessSearchQueryException("Invalid facet query: " + fq);
|
||||
}
|
||||
searchRequestBuilder.addAggregation(filterBuilder);
|
||||
} else {
|
||||
throw new FessSearchQueryException("Invalid facet query: " + facetQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BoolFilterBuilder boolFilterBuilder = null;
|
||||
|
||||
// query
|
||||
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(q);
|
||||
// filter query
|
||||
if (searchQuery.hasFilterQueries()) {
|
||||
if (boolFilterBuilder == null) {
|
||||
boolFilterBuilder = FilterBuilders.boolFilter();
|
||||
}
|
||||
for (final String filterQuery : searchQuery.getFilterQueries()) {
|
||||
boolFilterBuilder.must(FilterBuilders.queryFilter(QueryBuilders.queryStringQuery(filterQuery)));
|
||||
}
|
||||
}
|
||||
// geo
|
||||
if (geoInfo != null && geoInfo.isAvailable()) {
|
||||
if (boolFilterBuilder == null) {
|
||||
boolFilterBuilder = FilterBuilders.boolFilter();
|
||||
}
|
||||
boolFilterBuilder.must(geoInfo.toFilterBuilder());
|
||||
}
|
||||
|
||||
if (boolFilterBuilder != null) {
|
||||
queryBuilder = QueryBuilders.filteredQuery(queryBuilder, boolFilterBuilder);
|
||||
}
|
||||
|
||||
searchRequestBuilder.setQuery(queryBuilder);
|
||||
searchRequestBuilder.setQuery(queryContext.getQueryBuilder());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class CrawlingSession extends BsCrawlingSession {
|
|||
asDocMeta().version(version);
|
||||
}
|
||||
|
||||
public void setCrawlingSessionInfoList(List<CrawlingSessionInfo> crawlingSessionInfoList) {
|
||||
public void setCrawlingSessionInfoList(final List<CrawlingSessionInfo> crawlingSessionInfoList) {
|
||||
this.crawlingSessionInfoList = crawlingSessionInfoList;
|
||||
}
|
||||
|
||||
|
|
|
@ -296,8 +296,8 @@ public class Crawler implements Serializable {
|
|||
}
|
||||
|
||||
try {
|
||||
FessConfig fessConfig = ComponentUtil.getComponent(FessConfig.class);
|
||||
Postbox postbox = ComponentUtil.getComponent(Postbox.class);
|
||||
final FessConfig fessConfig = ComponentUtil.getComponent(FessConfig.class);
|
||||
final Postbox postbox = ComponentUtil.getComponent(Postbox.class);
|
||||
CrawlerPostcard.droppedInto(postbox, postcard -> {
|
||||
postcard.setFrom(fessConfig.getMailFromAddress(), fessConfig.getMailFromName());
|
||||
postcard.addReplyTo(fessConfig.getMailReturnPath());
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -151,7 +151,7 @@ public class SearchLogHelper {
|
|||
final Map<String, UserInfo> userInfoMap = new HashMap<>();
|
||||
queue.stream().forEach(searchLog -> {
|
||||
final String userAgent = searchLog.getUserAgent();
|
||||
boolean isBot = userAgent != null && Stream.of(botNames).anyMatch(botName -> userAgent.indexOf(botName) >= 0);
|
||||
final boolean isBot = userAgent != null && Stream.of(botNames).anyMatch(botName -> userAgent.indexOf(botName) >= 0);
|
||||
if (!isBot) {
|
||||
searchLog.getUserInfo().ifPresent(userInfo -> {
|
||||
final String code = userInfo.getCode();
|
||||
|
@ -265,7 +265,7 @@ public class SearchLogHelper {
|
|||
.stream()
|
||||
.forEach(
|
||||
entry -> {
|
||||
String id = docIdMap.get(entry.getKey());
|
||||
final String id = docIdMap.get(entry.getKey());
|
||||
if (id != null) {
|
||||
builder.add(new UpdateRequest(fieldHelper.docIndex, fieldHelper.docType, id).doc(
|
||||
fieldHelper.clickCountField, entry.getValue()));
|
||||
|
|
|
@ -27,23 +27,23 @@ import java.net.URLEncoder;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.codelibs.core.CoreLibConstants;
|
||||
import org.codelibs.core.lang.StringUtil;
|
||||
import org.codelibs.core.misc.Base64Util;
|
||||
import org.codelibs.core.misc.DynamicProperties;
|
||||
import org.codelibs.core.net.URLUtil;
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.app.service.DataConfigService;
|
||||
import org.codelibs.fess.app.service.FileConfigService;
|
||||
|
@ -101,7 +101,7 @@ public class ViewHelper implements Serializable {
|
|||
|
||||
public String urlLinkEncoding = Constants.UTF_8;
|
||||
|
||||
public String[] highlightingFields = new String[] { "hl_content", "digest" };
|
||||
public String[] highlightedFields = new String[] { "hl_content", "digest" };
|
||||
|
||||
public boolean useHighlight = false;
|
||||
|
||||
|
@ -158,11 +158,16 @@ public class ViewHelper implements Serializable {
|
|||
}
|
||||
|
||||
public String getContentDescription(final Map<String, Object> document) {
|
||||
final HttpServletRequest request = LaRequestUtil.getOptionalRequest().orElse(null);
|
||||
final String[] queries = request == null ? StringUtil.EMPTY_STRINGS : (String[]) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
|
||||
final Set<String> queries = new HashSet<>();
|
||||
LaRequestUtil.getOptionalRequest().ifPresent(request -> {
|
||||
Set<String> set = (Set<String>) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
|
||||
if (set != null) {
|
||||
queries.addAll(set);
|
||||
}
|
||||
});
|
||||
final int size = descriptionLength;
|
||||
|
||||
for (final String field : highlightingFields) {
|
||||
for (final String field : highlightedFields) {
|
||||
final String text = getString(document, field);
|
||||
if (StringUtil.isNotBlank(text)) {
|
||||
if (useHighlight) {
|
||||
|
@ -185,8 +190,9 @@ public class ViewHelper implements Serializable {
|
|||
return str.replaceAll(originalHighlightTagPre, StringUtil.EMPTY).replaceAll(originalHighlightTagPost, StringUtil.EMPTY);
|
||||
}
|
||||
|
||||
protected String highlight(final String content, final String[] queries) {
|
||||
if (StringUtil.isBlank(content) || queries == null || queries.length == 0) {
|
||||
@Deprecated
|
||||
protected String highlight(final String content, final Set<String> queries) {
|
||||
if (StringUtil.isBlank(content) || queries.isEmpty()) {
|
||||
return content;
|
||||
}
|
||||
String newContent = content;
|
||||
|
@ -313,16 +319,11 @@ public class ViewHelper implements Serializable {
|
|||
}
|
||||
|
||||
protected String appendPDFSearchWord(final String url) {
|
||||
final String[] queries = (String[]) LaRequestUtil.getRequest().getAttribute(Constants.HIGHLIGHT_QUERIES);
|
||||
final Set<String> queries = (Set<String>) LaRequestUtil.getRequest().getAttribute(Constants.HIGHLIGHT_QUERIES);
|
||||
if (queries != null) {
|
||||
final StringBuilder buf = new StringBuilder(url.length() + 100);
|
||||
buf.append(url).append("#search=%22");
|
||||
for (int i = 0; i < queries.length; i++) {
|
||||
if (i != 0) {
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append(URLUtil.encode(queries[i], urlLinkEncoding));
|
||||
}
|
||||
buf.append(String.join(" ", queries.toArray(new String[queries.size()])));
|
||||
buf.append("%22");
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
|
@ -512,7 +512,7 @@ public class FessLabels extends ActionMessages {
|
|||
/** The key of the message: Scheduler */
|
||||
public static final String LABELS_menu_scheduled_job_config = "{labels.menu_scheduled_job_config}";
|
||||
|
||||
/** The key of the message: System */
|
||||
/** The key of the message: Dashboard */
|
||||
public static final String LABELS_menu_system_config = "{labels.menu_system_config}";
|
||||
|
||||
/** The key of the message: Index */
|
||||
|
@ -632,7 +632,7 @@ public class FessLabels extends ActionMessages {
|
|||
/** The key of the message: Search... */
|
||||
public static final String LABELS_SIDEBAR_placeholder_search = "{labels.sidebar.placeholder_search}";
|
||||
|
||||
/** The key of the message: Copyright(C) 2009-2015 CodeLibs Project. <span class="br-phone"></span>All Rights Reserved. */
|
||||
/** The key of the message: Copyright(C) 2009-2015 <a href="https://github.com/codelibs">CodeLibs Project</a>. <span class="br-phone"></span>All Rights Reserved. */
|
||||
public static final String LABELS_FOOTER_COPYRIGHT = "{labels.footer.copyright}";
|
||||
|
||||
/** The key of the message: Search */
|
||||
|
@ -839,11 +839,17 @@ public class FessLabels extends ActionMessages {
|
|||
/** The key of the message: Login */
|
||||
public static final String LABELS_LOGIN = "{labels.login}";
|
||||
|
||||
/** The key of the message: User name */
|
||||
public static final String LABELS_LOGIN_placeholder_username = "{labels.login.placeholder_username}";
|
||||
|
||||
/** The key of the message: Password */
|
||||
public static final String LABELS_LOGIN_placeholder_password = "{labels.login.placeholder_password}";
|
||||
|
||||
/** The key of the message: Copyright(C) 2009-2014 CodeLibs Project. All Rights Reserved. */
|
||||
public static final String LABELS_LOGIN_footer_copyright = "{labels.login.footer_copyright}";
|
||||
|
||||
/** The key of the message: Login */
|
||||
public static final String LABELS_login_title = "{labels.login_title}";
|
||||
public static final String LABELS_LOGIN_TITLE = "{labels.login.title}";
|
||||
|
||||
/** The key of the message: Labels */
|
||||
public static final String LABELS_index_label = "{labels.index_label}";
|
||||
|
@ -1115,7 +1121,7 @@ public class FessLabels extends ActionMessages {
|
|||
/** The key of the message: Remove Index Before */
|
||||
public static final String LABELS_day_for_cleanup = "{labels.day_for_cleanup}";
|
||||
|
||||
/** The key of the message: Day */
|
||||
/** The key of the message: Day(s) */
|
||||
public static final String LABELS_DAY = "{labels.day}";
|
||||
|
||||
/** The key of the message: Update */
|
||||
|
|
|
@ -294,7 +294,7 @@ public class FessMessages extends FessLabels {
|
|||
/** The key of the message: Invalid password. */
|
||||
public static final String ERRORS_password_does_not_exist_in_session = "{errors.password_does_not_exist_in_session}";
|
||||
|
||||
/** The key of the message: The given query is invalid. */
|
||||
/** The key of the message: The given query has unknown condition. */
|
||||
public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
|
||||
|
||||
/** The key of the message: An invalid quote character is used. */
|
||||
|
@ -315,6 +315,18 @@ public class FessMessages extends FessLabels {
|
|||
/** The key of the message: An invalid range is used. The example of the range format is "field:'{'Aida TO Carmen'}'". */
|
||||
public static final String ERRORS_invalid_query_str_range = "{errors.invalid_query_str_range}";
|
||||
|
||||
/** The key of the message: The given query is invalid. */
|
||||
public static final String ERRORS_invalid_query_parse_error = "{errors.invalid_query_parse_error}";
|
||||
|
||||
/** The key of the message: The given sort ({0}) is invalid. */
|
||||
public static final String ERRORS_invalid_query_sort_value = "{errors.invalid_query_sort_value}";
|
||||
|
||||
/** The key of the message: The given sort ({0}) is not supported. */
|
||||
public static final String ERRORS_invalid_query_unsupported_sort_field = "{errors.invalid_query_unsupported_sort_field}";
|
||||
|
||||
/** The key of the message: The given sort order ({0}) is not supported. */
|
||||
public static final String ERRORS_invalid_query_unsupported_sort_order = "{errors.invalid_query_unsupported_sort_order}";
|
||||
|
||||
/** The key of the message: Invalid mode(expected value is {0}, but it's {1}). */
|
||||
public static final String ERRORS_crud_invalid_mode = "{errors.crud_invalid_mode}";
|
||||
|
||||
|
@ -1786,7 +1798,7 @@ public class FessMessages extends FessLabels {
|
|||
/**
|
||||
* Add the created action message for the key 'errors.invalid_query_unknown' with parameters.
|
||||
* <pre>
|
||||
* message: The given query is invalid.
|
||||
* message: The given query has unknown condition.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
|
@ -1881,6 +1893,65 @@ public class FessMessages extends FessLabels {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.invalid_query_parse_error' with parameters.
|
||||
* <pre>
|
||||
* message: The given query is invalid.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsInvalidQueryParseError(String property) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new ActionMessage(ERRORS_invalid_query_parse_error));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.invalid_query_sort_value' with parameters.
|
||||
* <pre>
|
||||
* message: The given sort ({0}) is invalid.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsInvalidQuerySortValue(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new ActionMessage(ERRORS_invalid_query_sort_value, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.invalid_query_unsupported_sort_field' with parameters.
|
||||
* <pre>
|
||||
* message: The given sort ({0}) is not supported.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsInvalidQueryUnsupportedSortField(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new ActionMessage(ERRORS_invalid_query_unsupported_sort_field, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.invalid_query_unsupported_sort_order' with parameters.
|
||||
* <pre>
|
||||
* message: The given sort order ({0}) is not supported.
|
||||
* </pre>
|
||||
* @param property The property name for the message. (NotNull)
|
||||
* @param arg0 The parameter arg0 for message. (NotNull)
|
||||
* @return this. (NotNull)
|
||||
*/
|
||||
public FessMessages addErrorsInvalidQueryUnsupportedSortOrder(String property, String arg0) {
|
||||
assertPropertyNotNull(property);
|
||||
add(property, new ActionMessage(ERRORS_invalid_query_unsupported_sort_order, arg0));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the created action message for the key 'errors.crud_invalid_mode' with parameters.
|
||||
* <pre>
|
||||
|
|
|
@ -35,12 +35,6 @@ public interface FessEnv {
|
|||
/** The key of the configuration. e.g. root@localhost */
|
||||
String MAIL_RETURN_PATH = "mail.return.path";
|
||||
|
||||
/** The key of the configuration. e.g. UTF-8 */
|
||||
String TOMCAT_URIEncoding = "tomcat.URIEncoding";
|
||||
|
||||
/** The key of the configuration. e.g. true */
|
||||
String TOMCAT_USE_BODY_ENCODING_FORURI = "tomcat.useBodyEncodingForURI";
|
||||
|
||||
/**
|
||||
* Get the value of property as {@link String}.
|
||||
* @param propertyKey The key of the property. (NotNull)
|
||||
|
@ -162,28 +156,6 @@ public interface FessEnv {
|
|||
*/
|
||||
String getMailReturnPath();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'tomcat.URIEncoding'. <br>
|
||||
* The value is, e.g. UTF-8 <br>
|
||||
* comment: ------
|
||||
* @return The value of found property. (NotNull: if not found, exception but basically no way)
|
||||
*/
|
||||
String getTomcatURIEncoding();
|
||||
|
||||
/**
|
||||
* Get the value for the key 'tomcat.useBodyEncodingForURI'. <br>
|
||||
* The value is, e.g. true <br>
|
||||
* @return The value of found property. (NotNull: if not found, exception but basically no way)
|
||||
*/
|
||||
String getTomcatUseBodyEncodingForuri();
|
||||
|
||||
/**
|
||||
* Is the property for the key 'tomcat.useBodyEncodingForURI' true? <br>
|
||||
* The value is, e.g. true <br>
|
||||
* @return The determination, true or false. (if not found, exception but basically no way)
|
||||
*/
|
||||
boolean isTomcatUseBodyEncodingForuri();
|
||||
|
||||
/**
|
||||
* The simple implementation for configuration.
|
||||
* @author FreeGen
|
||||
|
@ -244,17 +216,5 @@ public interface FessEnv {
|
|||
public String getMailReturnPath() {
|
||||
return get(FessEnv.MAIL_RETURN_PATH);
|
||||
}
|
||||
|
||||
public String getTomcatURIEncoding() {
|
||||
return get(FessEnv.TOMCAT_URIEncoding);
|
||||
}
|
||||
|
||||
public String getTomcatUseBodyEncodingForuri() {
|
||||
return get(FessEnv.TOMCAT_USE_BODY_ENCODING_FORURI);
|
||||
}
|
||||
|
||||
public boolean isTomcatUseBodyEncodingForuri() {
|
||||
return is(FessEnv.TOMCAT_USE_BODY_ENCODING_FORURI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
src/main/java/org/codelibs/fess/util/StreamUtil.java
Normal file
15
src/main/java/org/codelibs/fess/util/StreamUtil.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package org.codelibs.fess.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class StreamUtil {
|
||||
public static <T> Stream<T> of(final T... values) {
|
||||
if (values != null) {
|
||||
return Arrays.stream(values);
|
||||
} else {
|
||||
return Collections.<T> emptyList().stream();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -125,13 +125,17 @@ errors.blank_password=Password is required.
|
|||
errors.invalid_confirm_password=Confirm Password does not match.
|
||||
errors.password_does_not_exist_in_session=Invalid password.
|
||||
|
||||
errors.invalid_query_unknown=The given query is invalid.
|
||||
errors.invalid_query_unknown=The given query has unknown condition.
|
||||
errors.invalid_query_quoted=An invalid quote character is used.
|
||||
errors.invalid_query_curly_bracket=An invalid curly bracket character is used.
|
||||
errors.invalid_query_square_bracket=An invalid square bracket character is used.
|
||||
errors.invalid_query_parenthesis=An invalid parenthesis character is used.
|
||||
errors.invalid_query_num_range=An invalid range is used. The example of the range format is "field:[20020101 TO 20030101]".
|
||||
errors.invalid_query_str_range=An invalid range is used. The example of the range format is "field:'{'Aida TO Carmen'}'".
|
||||
errors.invalid_query_parse_error=The given query is invalid.
|
||||
errors.invalid_query_sort_value=The given sort ({0}) is invalid.
|
||||
errors.invalid_query_unsupported_sort_field=The given sort ({0}) is not supported.
|
||||
errors.invalid_query_unsupported_sort_order=The given sort order ({0}) is not supported.
|
||||
|
||||
errors.crud_invalid_mode=Invalid mode(expected value is {0}, but it's {1}).
|
||||
errors.crud_failed_to_create_crud_table=Failed to create a new data.
|
||||
|
|
1694
src/test/java/org/codelibs/fess/helper/QueryHelperTest.java
Normal file
1694
src/test/java/org/codelibs/fess/helper/QueryHelperTest.java
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue