Skip to content
This repository has been archived by the owner on Sep 19, 2023. It is now read-only.

Commit

Permalink
DATASOLR-244 - Added Support for Combined Facet and Highlight Query.
Browse files Browse the repository at this point in the history
Original Pull Request: #65 (David Webb)
  • Loading branch information
prowave authored and christophstrobl committed May 23, 2016
1 parent 955f7c9 commit fe12122
Show file tree
Hide file tree
Showing 17 changed files with 714 additions and 173 deletions.
Expand Up @@ -36,13 +36,15 @@
import org.springframework.data.solr.core.convert.DateTimeConverters;
import org.springframework.data.solr.core.convert.NumberConverters;
import org.springframework.data.solr.core.geo.GeoConverters;
import org.springframework.data.solr.core.query.AbstractFacetAndHighlightQueryDecorator;
import org.springframework.data.solr.core.query.AbstractFacetQueryDecorator;
import org.springframework.data.solr.core.query.AbstractHighlightQueryDecorator;
import org.springframework.data.solr.core.query.AbstractQueryDecorator;
import org.springframework.data.solr.core.query.CalculatedField;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Criteria.OperationKey;
import org.springframework.data.solr.core.query.Criteria.Predicate;
import org.springframework.data.solr.core.query.FacetAndHighlightQuery;
import org.springframework.data.solr.core.query.FacetQuery;
import org.springframework.data.solr.core.query.Field;
import org.springframework.data.solr.core.query.Function;
Expand All @@ -62,6 +64,7 @@
* @author Christoph Strobl
* @author Francisco Spaeth
* @author Radek Mensik
* @author David Webb
*/
public abstract class QueryParserBase<QUERYTPYE extends SolrDataQuery> implements QueryParser {

Expand Down Expand Up @@ -181,7 +184,7 @@ protected String createQueryStringFromCriteria(Criteria criteria) {
* @return
*/
protected String createQueryFragmentForCriteria(Criteria part) {
Criteria criteria = (Criteria) part;
Criteria criteria = part;
StringBuilder queryFragment = new StringBuilder();
boolean singeEntryCriteria = (criteria.getPredicates().size() == 1);
if (criteria instanceof QueryStringHolder) {
Expand Down Expand Up @@ -841,4 +844,28 @@ public Map<String, Object> getNamesAssociation() {

}

/**
* @author David Webb
*/
static class NamedObjectsFacetAndHighlightQuery extends AbstractFacetAndHighlightQueryDecorator
implements NamedObjects {

private Map<String, Object> namesAssociation = new HashMap<String, Object>();

public NamedObjectsFacetAndHighlightQuery(FacetAndHighlightQuery query) {
super(query);
}

@Override
public void setName(Object object, String name) {
setObjectName(namesAssociation, object, name);
}

@Override
public Map<String, Object> getNamesAssociation() {
return Collections.unmodifiableMap(namesAssociation);
}

}

}
Expand Up @@ -24,12 +24,14 @@
import org.apache.solr.common.SolrInputDocument;
import org.springframework.data.domain.Page;
import org.springframework.data.solr.core.convert.SolrConverter;
import org.springframework.data.solr.core.query.FacetAndHighlightQuery;
import org.springframework.data.solr.core.query.FacetQuery;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SolrDataQuery;
import org.springframework.data.solr.core.query.TermsQuery;
import org.springframework.data.solr.core.query.result.Cursor;
import org.springframework.data.solr.core.query.result.FacetAndHighlightPage;
import org.springframework.data.solr.core.query.result.FacetPage;
import org.springframework.data.solr.core.query.result.GroupPage;
import org.springframework.data.solr.core.query.result.HighlightPage;
Expand All @@ -44,6 +46,7 @@
* @author Joachim Uhrlass
* @author Francisco Spaeth
* @author Shiradwade Sateesh Krishna
* @author David Webb
*/
public interface SolrOperations {

Expand Down Expand Up @@ -251,6 +254,26 @@ public interface SolrOperations {
*/
<T> HighlightPage<T> queryForHighlightPage(HighlightQuery query, Class<T> clazz, RequestMethod method);

/**
* Execute a query and highlight matches in result
*
* @param query
* @param clazz
* @return
*/
<T> FacetAndHighlightPage<T> queryForFacetAndHighlightPage(FacetAndHighlightQuery query, Class<T> clazz);

/**
* Execute a query and highlight matches in result
*
* @param query
* @param clazz
* @param method must not be {@literal null}.
* @return
*/
<T> FacetAndHighlightPage<T> queryForFacetAndHighlightPage(FacetAndHighlightQuery query, Class<T> clazz,
RequestMethod method);

/**
* Execute query using terms handler
*
Expand Down
Expand Up @@ -50,6 +50,7 @@
import org.springframework.data.solr.SolrRealtimeGetRequest;
import org.springframework.data.solr.UncategorizedSolrException;
import org.springframework.data.solr.VersionUtil;
import org.springframework.data.solr.core.QueryParserBase.NamedObjectsFacetAndHighlightQuery;
import org.springframework.data.solr.core.QueryParserBase.NamedObjectsFacetQuery;
import org.springframework.data.solr.core.QueryParserBase.NamedObjectsHighlightQuery;
import org.springframework.data.solr.core.QueryParserBase.NamedObjectsQuery;
Expand All @@ -58,13 +59,15 @@
import org.springframework.data.solr.core.mapping.SimpleSolrMappingContext;
import org.springframework.data.solr.core.mapping.SolrPersistentEntity;
import org.springframework.data.solr.core.mapping.SolrPersistentProperty;
import org.springframework.data.solr.core.query.FacetAndHighlightQuery;
import org.springframework.data.solr.core.query.FacetQuery;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SolrDataQuery;
import org.springframework.data.solr.core.query.TermsQuery;
import org.springframework.data.solr.core.query.result.Cursor;
import org.springframework.data.solr.core.query.result.DelegatingCursor;
import org.springframework.data.solr.core.query.result.FacetAndHighlightPage;
import org.springframework.data.solr.core.query.result.FacetPage;
import org.springframework.data.solr.core.query.result.GroupPage;
import org.springframework.data.solr.core.query.result.HighlightPage;
Expand All @@ -89,6 +92,7 @@
* @author Joachim Uhrlass
* @author Francisco Spaeth
* @author Shiradwade Sateesh Krishna
* @author David Webb
*/
public class SolrTemplate implements SolrOperations, InitializingBean, ApplicationContextAware {

Expand Down Expand Up @@ -326,7 +330,7 @@ public <T> T queryForObject(Query query, Class<T> clazz, RequestMethod method) {
if (response.getResults().size() > 1) {
LOGGER.warn("More than 1 result found for singe result query ('{}'), returning first entry in list");
}
return (T) convertSolrDocumentListToBeans(response.getResults(), clazz).get(0);
return convertSolrDocumentListToBeans(response.getResults(), clazz).get(0);
}
return null;
}
Expand Down Expand Up @@ -446,6 +450,36 @@ public <T> HighlightPage<T> queryForHighlightPage(HighlightQuery query, Class<T>
return page;
}

@Override
public <T> FacetAndHighlightPage<T> queryForFacetAndHighlightPage(FacetAndHighlightQuery query, Class<T> clazz) {
return queryForFacetAndHighlightPage(query, clazz, getDefaultRequestMethod());
}

@Override
public <T> FacetAndHighlightPage<T> queryForFacetAndHighlightPage(FacetAndHighlightQuery query, Class<T> clazz,
RequestMethod method) {

Assert.notNull(query, "Query must not be 'null'.");
Assert.notNull(clazz, "Target class must not be 'null'.");

NamedObjectsFacetAndHighlightQuery namedObjectsFacetAndHighlightQuery = new NamedObjectsFacetAndHighlightQuery(
query);

QueryResponse response = query(namedObjectsFacetAndHighlightQuery, clazz, method);
Map<String, Object> objectsName = namedObjectsFacetAndHighlightQuery.getNamesAssociation();

SolrResultPage<T> page = createSolrResultPage(query, clazz, response, objectsName);

ResultHelper.convertAndAddHighlightQueryResponseToResultPage(response, page);

page.addAllFacetFieldResultPages(ResultHelper.convertFacetQueryResponseToFacetPageMap(query, response));
page.addAllFacetPivotFieldResult(ResultHelper.convertFacetQueryResponseToFacetPivotMap(query, response));
page.addAllRangeFacetFieldResultPages(ResultHelper.convertFacetQueryResponseToRangeFacetPageMap(query, response));
page.setFacetQueryResultPage(ResultHelper.convertFacetQueryResponseToFacetQueryResult(query, response));

return page;
}

private <T> SolrResultPage<T> createSolrResultPage(Query query, Class<T> clazz, QueryResponse response,
Map<String, Object> objectsName) {
List<T> beans = convertQueryResponseToBeans(response, clazz);
Expand Down Expand Up @@ -582,6 +616,7 @@ public String doInSolr(SolrClient solrClient) throws SolrServerException, IOExce
* (non-Javadoc)
* @see org.springframework.data.solr.core.SolrOperations#queryForCursor(org.springframework.data.solr.core.query.Query, java.lang.Class)
*/
@Override
public <T> Cursor<T> queryForCursor(Query query, final Class<T> clazz) {

return new DelegatingCursor<T>(queryParsers.getForClass(query.getClass()).constructSolrQuery(query)) {
Expand Down
@@ -0,0 +1,64 @@
/*
* Copyright 2012 - 2016 the original author or authors.
*
* 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.springframework.data.solr.core.query;

/**
* General purpose {@link FacetAndHighlightQuery} decorator.
*
* @author David Webb
* @since 2.1.0
*/
public class AbstractFacetAndHighlightQueryDecorator extends AbstractQueryDecorator
implements FacetQuery, HighlightQuery {

private FacetAndHighlightQuery query;

public AbstractFacetAndHighlightQueryDecorator(FacetAndHighlightQuery query) {

super(query);
this.query = query;
}

@Override
public <T extends SolrDataQuery> T setHighlightOptions(HighlightOptions highlightOptions) {
return query.setHighlightOptions(highlightOptions);
}

@Override
public HighlightOptions getHighlightOptions() {
return query.getHighlightOptions();
}

@Override
public boolean hasHighlightOptions() {
return query.hasHighlightOptions();
}

@Override
public <T extends SolrDataQuery> T setFacetOptions(FacetOptions facetOptions) {
return query.setFacetOptions(facetOptions);
}

@Override
public FacetOptions getFacetOptions() {
return query.getFacetOptions();
}

@Override
public boolean hasFacetOptions() {
return query.hasFacetOptions();
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2012 - 2016 the original author or authors.
*
* 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.springframework.data.solr.core.query;

/**
* A Query that combines a {@link FacetQuery} and a {@link HighlightQuery}
*
* @author David Webb
* @since 2.1.0
*/
public interface FacetAndHighlightQuery extends FacetQuery, HighlightQuery {

}
@@ -0,0 +1,81 @@
/*
* Copyright 2012 - 2016 the original author or authors.
*
* 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.springframework.data.solr.core.query;

import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;

/**
* Trivial implementation of {@link FacetAndHighlightQuery}
*
* @author David Webb
* @since 2.1.0
*/
public class SimpleFacetAndHighlightQuery extends SimpleQuery implements FacetAndHighlightQuery {

private FacetOptions facetOptions;
private HighlightOptions highlightOptions;

public SimpleFacetAndHighlightQuery() {
super();
}

public SimpleFacetAndHighlightQuery(Criteria criteria) {
this(criteria, null);
}

public SimpleFacetAndHighlightQuery(Criteria criteria, Pageable pageable) {
super(criteria, pageable);
}

@SuppressWarnings("unchecked")
@Override
public final <T extends SolrDataQuery> T setFacetOptions(FacetOptions facetOptions) {
if (facetOptions != null) {
Assert.isTrue(facetOptions.hasFacets(), "Cannot set facet options having neither fields nor queries.");
}
this.facetOptions = facetOptions;
return (T) this;
}

@Override
public FacetOptions getFacetOptions() {
return this.facetOptions;
}

@Override
public boolean hasFacetOptions() {
return this.getFacetOptions() != null;
}

@SuppressWarnings("unchecked")
@Override
public <T extends SolrDataQuery> T setHighlightOptions(HighlightOptions highlightOptions) {
this.highlightOptions = highlightOptions;
return (T) this;
}

@Override
public HighlightOptions getHighlightOptions() {
return this.highlightOptions;
}

@Override
public boolean hasHighlightOptions() {
return this.highlightOptions != null;
}

}

0 comments on commit fe12122

Please sign in to comment.