Be careful with stats query, because the stats will only return with the current query ie you search for Widgets in between $1 - $100, if you do a new range query for products between $25 - $50, your stats will now return 25 - 50.
You should do 2 separate queries if any facets are active.
Here's some things that may help you, what this does is extends FieldImpl to pass in the min and max stats. With a bit of extra stuff, the url params instead of looking like this: price=range[10:100], if I assign min post fix to say '-min' and my max postfix to '-max' and I set isAdHocRange = true. My new urls can now look like: price-min=10&price-max=100 to use with something like this
http://refreshless.com/nouislider/ , requestmin and requestmax is to pass what ever the current range is in the url to the slider defaults the handles to those positions
Code: Select all
@Entity
@Table(name = "PSS_FIELD_EXTENSION")
public class FieldExtensionImpl extends FieldImpl implements FieldExtension, Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "AD_HOC_RANGE")
protected Boolean isAdHocRange = false;
@Column(name = "MIN_POST_FIX")
protected String minPostfix;
@Column(name = "MAX_POST_FIX")
protected String maxPostfix;
@Column(name = "INCREMENT")
protected BigDecimal increment;
@Column(name="SORTABLE")
protected Boolean isSortable = false;
@Transient
protected Integer minValue;
@Transient
protected Integer maxValue;
@Transient
protected BigDecimal requestMin;
@Transient
protected BigDecimal requestMax;
@Override
public Boolean getIsAdHocRange() {
return isAdHocRange;
}
@Override
public void setIsAdHocRange(Boolean isAdHocRange) {
this.isAdHocRange = isAdHocRange;
}
@Override
public String getMinPostfix() {
return minPostfix;
}
@Override
public void setMinPostfix(String minPostfix) {
this.minPostfix = minPostfix;
}
@Override
public String getMaxPostfix() {
return maxPostfix;
}
@Override
public void setMaxPostfix(String maxPostfix) {
this.maxPostfix = maxPostfix;
}
@Override
public BigDecimal getIncrement() {
return increment != null ? increment : new BigDecimal(1);
}
@Override
public void setIncrement(BigDecimal increment) {
this.increment = increment;
}
@Override
public String getFormattedName() {
return getAbbreviation() + "_" + getFacetFieldType().getType();
}
@Override
public String getFormattedMinName() {
return getAbbreviation() + getMinPostfix();
}
@Override
public String getFormattedMaxName() {
return getAbbreviation() + getMaxPostfix();
}
@Override
public Integer getMinValue() {
return minValue;
}
@Override
public void setMinValue(Integer minValue) {
this.minValue = minValue;
}
@Override
public Integer getMaxValue() {
return maxValue;
}
@Override
public void setMaxValue(Integer maxValue) {
this.maxValue = maxValue;
}
@Override
public BigDecimal getRequestMin() {
return requestMin != null ? requestMin : new BigDecimal(minValue);
}
@Override
public void setRequestMin(BigDecimal requestMin) {
this.requestMin = requestMin;
}
@Override
public BigDecimal getRequestMax() {
return requestMax != null ? requestMax : new BigDecimal(maxValue);
}
@Override
public void setRequestMax(BigDecimal requestMax) {
this.requestMax = requestMax;
}
@Override
public Boolean getIsSortable() {
return isSortable;
}
@Override
public void setIsSortable(Boolean isSortable) {
this.isSortable = isSortable;
}
@Override
public String toJsonString() {
final StringBuilder sb = new StringBuilder(getAbbreviation()).append(":{");
sb.append("abbreviation:'").append(getAbbreviation()).append('\'');
sb.append(", isAdHocRange:").append(isAdHocRange);
sb.append(", entityType:'").append(entityType).append('\'');
sb.append(", formattedName:'").append(getFormattedName()).append('\'');
if(isAdHocRange) {
sb.append(", rangeInfo: {");
sb.append("increment:").append(getIncrement());
sb.append(", minValue:").append(minValue);
sb.append(", maxValue:").append(maxValue);
sb.append(", requestMin:").append(getRequestMin());
sb.append(", requestMax:").append(getRequestMax());
sb.append(", formattedMinName:'").append(getFormattedMinName()).append('\'');
sb.append(", formattedMaxName:'").append(getFormattedMaxName()).append('\'');
sb.append("}");
}
sb.append('}');
return sb.toString();
}
}
Add this to my own extension of SolrSearchServiceImpl
Code: Select all
private void getFacet(SearchCriteria searchCriteria, List<String> queryParams, Map.Entry<String, String[]> param, Map.Entry<String, SearchFacetDTO> dtoEntry) {
FieldExtension fieldExtension = (FieldExtension) dtoEntry.getValue().getFacet().getField();
if(fieldExtension.getAbbreviation().equals(param.getKey())){
for(String p : param.getValue()){
queryParams.add(fieldExtension.getFormattedName()+ ":\"" + p + "\"");
}
dtoEntry.getValue().setActive(true);
} else if(fieldExtension.getIsAdHocRange()){
String facetName = fieldExtension.getFormattedMinName();
BigDecimal start = BigDecimalValidator.getInstance().validate(param.getValue()[0]);
BigDecimal end = null;
if(facetName.equals(param.getKey()) && start != null){
if(searchCriteria.getFilterCriteria().containsKey(fieldExtension.getFormattedMaxName())){
end = BigDecimalValidator.getInstance().validate(searchCriteria.getFilterCriteria().get(fieldExtension.getFormattedMaxName())[0]);
}
((FieldExtension) dtoEntry.getValue().getFacet().getField()).setRequestMin(start);
if(end != null){
((FieldExtension) dtoEntry.getValue().getFacet().getField()).setRequestMax(end);
queryParams.add(fieldExtension.getFormattedName() + ":[" + start.toString() + " TO " + end.toString() + "]");
}else{
queryParams.add(fieldExtension.getFormattedName() + ":[" + start.toString() + " TO *]");
}
}
dtoEntry.getValue().setActive(true);
}
}
Code: Select all
private QueryResponse getStatQuery(String qualifiedSolrQuery, String[] filterQueries) throws ServiceException {
SolrQuery statQuery = new SolrQuery().setQuery(qualifiedSolrQuery);
statQuery.setParam("stats", true);
List<Field> rangeFields = ((FieldDaoExtension) fieldDao).readAllRangeFields();
String[] statFields = new String[rangeFields.size()];
for(int i = 0; i < rangeFields.size(); i++){
statFields[i] = ((FieldExtension) rangeFields.get(i)).getFormattedName();
}
statQuery.add("stats.field", statFields);
statQuery.setFilterQueries(filterQueries);
QueryResponse stats;
try {
stats = SolrContext.getServer().query(statQuery);
}
catch (SolrServerException e) {
throw new ServiceException("Could not perform search", e);
}
return stats;
}
Modified the body of findSearchResults
Code: Select all
...
QueryResponse stats = getStatQuery(qualifiedSolrQuery, filterQueries);
for(SearchFacetDTO facet : facets){
if(((FieldExtension) facet.getFacet().getField()).getIsAdHocRange() != null && ((FieldExtension) facet.getFacet().getField()).getIsAdHocRange()) {
if (stats.getFieldStatsInfo().containsKey(((FieldExtension) facet.getFacet().getField()).getFormattedName())) {
Double validateMin = new DoubleValidator().validate(stats.getFieldStatsInfo().get(((FieldExtension) facet.getFacet().getField()).getFormattedName()).getMin().toString());
Double validateMax = new DoubleValidator().validate(stats.getFieldStatsInfo().get(((FieldExtension) facet.getFacet().getField()).getFormattedName()).getMax().toString());
if(validateMin != null ){
Double min = Math.floor(validateMin);
((FieldExtension) facet.getFacet().getField()).setMinValue(min.intValue());
}
if(validateMax != null){
Double max = Math.ceil(validateMax);
((FieldExtension) facet.getFacet().getField()).setMaxValue(max.intValue());
}
}
}
}
...