/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.solr.client.solrj; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.FacetParams; import org.apache.solr.common.params.HighlightParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.StatsParams; import org.apache.solr.common.params.TermsParams; import java.util.regex.Pattern; /** * This is an augmented SolrParams with get/set/add fields for common fields used * in the Standard and Dismax request handlers * * @version $Id: SolrQuery.java 890053 2009-12-13 11:58:37Z shalin $ * @since solr 1.3 */ public class SolrQuery extends ModifiableSolrParams { public enum ORDER { desc, asc; public ORDER reverse() { return (this == asc) ? desc : asc; } } public SolrQuery() { super(); } /** Create a new SolrQuery * * @param q query string */ public SolrQuery(String q) { this(); this.set(CommonParams.Q, q); } /** enable/disable terms. * * @param b flag to indicate terms should be enabled. <br /> if b==false, removes all other terms parameters * @return Current reference (<i>this</i>) */ public SolrQuery setTerms(boolean b) { if (b) { this.set(TermsParams.TERMS, true); } else { this.remove(TermsParams.TERMS); this.remove(TermsParams.TERMS_FIELD); this.remove(TermsParams.TERMS_LOWER); this.remove(TermsParams.TERMS_UPPER); this.remove(TermsParams.TERMS_UPPER_INCLUSIVE); this.remove(TermsParams.TERMS_LOWER_INCLUSIVE); this.remove(TermsParams.TERMS_LIMIT); this.remove(TermsParams.TERMS_PREFIX_STR); this.remove(TermsParams.TERMS_MINCOUNT); this.remove(TermsParams.TERMS_MAXCOUNT); this.remove(TermsParams.TERMS_RAW); this.remove(TermsParams.TERMS_SORT); this.remove(TermsParams.TERMS_REGEXP_STR); this.remove(TermsParams.TERMS_REGEXP_FLAG); } return this; } public boolean getTerms() { return this.getBool(TermsParams.TERMS, false); } public SolrQuery addTermsField(String field) { this.add(TermsParams.TERMS_FIELD, field); return this; } public String[] getTermsFields() { return this.getParams(TermsParams.TERMS_FIELD); } public SolrQuery setTermsLower(String lower) { this.set(TermsParams.TERMS_LOWER, lower); return this; } public String getTermsLower() { return this.get(TermsParams.TERMS_LOWER, ""); } public SolrQuery setTermsUpper(String upper) { this.set(TermsParams.TERMS_UPPER, upper); return this; } public String getTermsUpper() { return this.get(TermsParams.TERMS_UPPER, ""); } public SolrQuery setTermsUpperInclusive(boolean b) { this.set(TermsParams.TERMS_UPPER_INCLUSIVE, b); return this; } public boolean getTermsUpperInclusive() { return this.getBool(TermsParams.TERMS_UPPER_INCLUSIVE, false); } public SolrQuery setTermsLowerInclusive(boolean b) { this.set(TermsParams.TERMS_LOWER_INCLUSIVE, b); return this; } public boolean getTermsLowerInclusive() { return this.getBool(TermsParams.TERMS_LOWER_INCLUSIVE, true); } public SolrQuery setTermsLimit(int limit) { this.set(TermsParams.TERMS_LIMIT, limit); return this; } public int getTermsLimit() { return this.getInt(TermsParams.TERMS_LIMIT, 10); } public SolrQuery setTermsMinCount(int cnt) { this.set(TermsParams.TERMS_MINCOUNT, cnt); return this; } public int getTermsMinCount() { return this.getInt(TermsParams.TERMS_MINCOUNT, 1); } public SolrQuery setTermsMaxCount(int cnt) { this.set(TermsParams.TERMS_MAXCOUNT, cnt); return this; } public int getTermsMaxCount() { return this.getInt(TermsParams.TERMS_MAXCOUNT, -1); } public SolrQuery setTermsPrefix(String prefix) { this.set(TermsParams.TERMS_PREFIX_STR, prefix); return this; } public String getTermsPrefix() { return this.get(TermsParams.TERMS_PREFIX_STR, ""); } public SolrQuery setTermsRaw(boolean b) { this.set(TermsParams.TERMS_RAW, b); return this; } public boolean getTermsRaw() { return this.getBool(TermsParams.TERMS_RAW, false); } public SolrQuery setTermsSortString(String type) { this.set(TermsParams.TERMS_SORT, type); return this; } public String getTermsSortString() { return this.get(TermsParams.TERMS_SORT, TermsParams.TERMS_SORT_COUNT); } public SolrQuery setTermsRegex(String regex) { this.set(TermsParams.TERMS_REGEXP_STR, regex); return this; } public String getTermsRegex() { return this.get(TermsParams.TERMS_REGEXP_STR); } public SolrQuery setTermsRegexFlag(String flag) { this.add(TermsParams.TERMS_REGEXP_FLAG, flag); return this; } public String[] getTermsRegexFlags() { return this.getParams(TermsParams.TERMS_REGEXP_FLAG); } /** Add field(s) for facet computation. * * @param fields Array of field names from the IndexSchema * @return this */ public SolrQuery addFacetField(String ... fields) { add(FacetParams.FACET_FIELD, fields); this.set(FacetParams.FACET, true); return this; } /** get the facet fields * * @return string array of facet fields or null if not set/empty */ public String[] getFacetFields() { return this.getParams(FacetParams.FACET_FIELD); } /** remove a facet field * * @param name Name of the facet field to be removed. * * @return true, if the item was removed. <br /> * false, if the facet field was null or did not exist. */ public boolean removeFacetField(String name) { boolean b = this.remove(FacetParams.FACET_FIELD, name); if (this.get(FacetParams.FACET_FIELD) == null && this.get(FacetParams.FACET_QUERY) == null) { this.setFacet(false); } return b; } /** enable/disable faceting. * * @param b flag to indicate faceting should be enabled. <br /> if b==false, removes all other faceting parameters * @return Current reference (<i>this</i>) */ public SolrQuery setFacet(boolean b) { if (b) { this.set(FacetParams.FACET, true); } else { this.remove(FacetParams.FACET); this.remove(FacetParams.FACET_MINCOUNT); this.remove(FacetParams.FACET_FIELD); this.remove(FacetParams.FACET_LIMIT); this.remove(FacetParams.FACET_MISSING); this.remove(FacetParams.FACET_OFFSET); this.remove(FacetParams.FACET_PREFIX); this.remove(FacetParams.FACET_QUERY); this.remove(FacetParams.FACET_SORT); this.remove(FacetParams.FACET_ZEROS); this.remove(FacetParams.FACET_PREFIX); // does not include the individual fields... } return this; } public SolrQuery setFacetPrefix( String prefix ) { this.set( FacetParams.FACET_PREFIX, prefix ); return this; } public SolrQuery setFacetPrefix( String field, String prefix ) { this.set( "f."+field+"."+FacetParams.FACET_PREFIX, prefix ); return this; } /** add a faceting query * * @param f facet query */ public SolrQuery addFacetQuery(String f) { this.add(FacetParams.FACET_QUERY, f); return this; } /** get facet queries * * @return all facet queries or null if not set/empty */ public String[] getFacetQuery() { return this.getParams(FacetParams.FACET_QUERY); } /** remove a facet query * * @param q the facet query to remove * @return true if the facet query was removed false otherwise */ public boolean removeFacetQuery(String q) { boolean b = this.remove(FacetParams.FACET_QUERY, q); if (this.get(FacetParams.FACET_FIELD) == null && this.get(FacetParams.FACET_QUERY) == null) { this.setFacet(false); } return b; } /** set the facet limit * * @param lim number facet items to return */ public SolrQuery setFacetLimit(int lim) { this.set(FacetParams.FACET_LIMIT, lim); return this; } /** get current facet limit * * @return facet limit or default of 25 */ public int getFacetLimit() { return this.getInt(FacetParams.FACET_LIMIT, 25); } /** set facet minimum count * * @param cnt facets having less that cnt hits will be excluded from teh facet list */ public SolrQuery setFacetMinCount(int cnt) { this.set(FacetParams.FACET_MINCOUNT, cnt); return this; } /** get facet minimum count * * @return facet minimum count or default of 1 */ public int getFacetMinCount() { return this.getInt(FacetParams.FACET_MINCOUNT, 1); } /** * Sets facet missing boolean flag * * @param v flag to indicate the field of {@link FacetParams#FACET_MISSING} . * @return this */ public SolrQuery setFacetMissing(Boolean v) { this.set(FacetParams.FACET_MISSING, v); return this; } /** * @deprecated use {@link #setFacetMissing(Boolean)} */ public SolrQuery setMissing(String fld) { return setFacetMissing(Boolean.valueOf(fld)); } /** get facet sort * * @return facet sort or default of {@link FacetParams#FACET_SORT_COUNT} */ public String getFacetSortString() { return this.get(FacetParams.FACET_SORT, FacetParams.FACET_SORT_COUNT); } /** get facet sort * * @return facet sort or default of true. <br /> * true corresponds to * {@link FacetParams#FACET_SORT_COUNT} and <br />false to {@link FacetParams#FACET_SORT_INDEX} * * @deprecated Use {@link #getFacetSortString()} instead. */ @Deprecated public boolean getFacetSort() { return this.get(FacetParams.FACET_SORT, FacetParams.FACET_SORT_COUNT).equals(FacetParams.FACET_SORT_COUNT); } /** set facet sort * * @param sort sort facets * @return this */ public SolrQuery setFacetSort(String sort) { this.set(FacetParams.FACET_SORT, sort); return this; } /** set facet sort * * @param sort sort facets * @return this * @deprecated Use {@link #setFacetSort(String)} instead, true corresponds to * {@link FacetParams#FACET_SORT_COUNT} and false to {@link FacetParams#FACET_SORT_INDEX}. */ @Deprecated public SolrQuery setFacetSort(boolean sort) { this.set(FacetParams.FACET_SORT, sort == true ? FacetParams.FACET_SORT_COUNT : FacetParams.FACET_SORT_INDEX); return this; } /** add highlight field * * @param f field to enable for highlighting */ public SolrQuery addHighlightField(String f) { this.add(HighlightParams.FIELDS, f); this.set(HighlightParams.HIGHLIGHT, true); return this; } /** remove a field for highlighting * * @param f field name to not highlight * @return <i>true</i>, if removed, <br /> <i>false</i>, otherwise */ public boolean removeHighlightField(String f) { boolean b = this.remove(HighlightParams.FIELDS, f); if (this.get(HighlightParams.FIELDS) == null) { this.setHighlight(false); } return b; } /** get list of highlighted fields * * @return Array of highlight fields or null if not set/empty */ public String[] getHighlightFields() { return this.getParams(HighlightParams.FIELDS); } public SolrQuery setHighlightSnippets(int num) { this.set(HighlightParams.SNIPPETS, num); return this; } public int getHighlightSnippets() { return this.getInt(HighlightParams.SNIPPETS, 1); } public SolrQuery setHighlightFragsize(int num) { this.set(HighlightParams.FRAGSIZE, num); return this; } public int getHighlightFragsize() { return this.getInt(HighlightParams.FRAGSIZE, 100); } public SolrQuery setHighlightRequireFieldMatch(boolean flag) { this.set(HighlightParams.FIELD_MATCH, flag); return this; } public boolean getHighlightRequireFieldMatch() { return this.getBool(HighlightParams.FIELD_MATCH, false); } public SolrQuery setHighlightSimplePre(String f) { this.set(HighlightParams.SIMPLE_PRE, f); return this; } public String getHighlightSimplePre() { return this.get(HighlightParams.SIMPLE_PRE, ""); } public SolrQuery setHighlightSimplePost(String f) { this.set(HighlightParams.SIMPLE_POST, f); return this; } public String getHighlightSimplePost() { return this.get(HighlightParams.SIMPLE_POST, ""); } public SolrQuery setSortField(String field, ORDER order) { this.remove(CommonParams.SORT); addValueToParam(CommonParams.SORT, toSortString(field, order)); return this; } public SolrQuery addSortField(String field, ORDER order) { return addValueToParam(CommonParams.SORT, toSortString(field, order)); } public SolrQuery removeSortField(String field, ORDER order) { String s = this.get(CommonParams.SORT); String removeSort = toSortString(field, order); if (s != null) { String[] sorts = s.split(","); s = join(sorts, ", ", removeSort); if (s.length()==0) s=null; this.set(CommonParams.SORT, s); } return this; } public String[] getSortFields() { String s = getSortField(); if (s==null) return null; return s.split(","); } public String getSortField() { return this.get(CommonParams.SORT); } public void setGetFieldStatistics( boolean v ) { this.set( StatsParams.STATS, v ); } public void setGetFieldStatistics( String field ) { this.set( StatsParams.STATS, true ); this.add( StatsParams.STATS_FIELD, field ); } public void addStatsFieldFacets( String field, String ... facets ) { if( field == null ) { this.add( StatsParams.STATS_FACET, facets ); } else { for( String f : facets ) { this.add( "f."+field+"."+StatsParams.STATS_FACET, f ); } } } public SolrQuery setFilterQueries(String ... fq) { this.set(CommonParams.FQ, fq); return this; } public SolrQuery addFilterQuery(String ... fq) { this.add(CommonParams.FQ, fq); return this; } public boolean removeFilterQuery(String fq) { return this.remove(CommonParams.FQ, fq); } public String[] getFilterQueries() { return this.getParams(CommonParams.FQ); } public boolean getHighlight() { return this.getBool(HighlightParams.HIGHLIGHT, false); } public SolrQuery setHighlight(boolean b) { if (b) { this.set(HighlightParams.HIGHLIGHT, true); } else { this.remove(HighlightParams.HIGHLIGHT); this.remove(HighlightParams.FIELD_MATCH); this.remove(HighlightParams.FIELDS); this.remove(HighlightParams.FORMATTER); this.remove(HighlightParams.FRAGSIZE); this.remove(HighlightParams.SIMPLE_POST); this.remove(HighlightParams.SIMPLE_PRE); this.remove(HighlightParams.SNIPPETS); } return this; } public SolrQuery setFields(String ... fields) { if( fields == null || fields.length == 0 ) { this.remove( CommonParams.FL ); return this; } StringBuilder sb = new StringBuilder(); sb.append( fields[0] ); for( int i=1; i<fields.length; i++ ) { sb.append( ',' ); sb.append( fields[i] ); } this.set(CommonParams.FL, sb.toString() ); return this; } public SolrQuery addField(String field) { return addValueToParam(CommonParams.FL, field); } public String getFields() { String fields = this.get(CommonParams.FL); if (fields!=null && fields.equals("score")) { fields = "*, score"; } return fields; } private static Pattern scorePattern = Pattern.compile("(^|[, ])score"); public SolrQuery setIncludeScore(boolean includeScore) { String fields = get(CommonParams.FL,"*"); if (includeScore) { if (!scorePattern.matcher(fields).find()) { this.set(CommonParams.FL, fields+",score"); } } else { this.set(CommonParams.FL, scorePattern.matcher(fields).replaceAll("")); } return this; } public SolrQuery setQuery(String query) { this.set(CommonParams.Q, query); return this; } public String getQuery() { return this.get(CommonParams.Q); } public SolrQuery setRows(Integer rows) { if( rows == null ) { this.remove( CommonParams.ROWS ); } else { this.set(CommonParams.ROWS, rows); } return this; } public Integer getRows() { return this.getInt(CommonParams.ROWS); } public void setShowDebugInfo(boolean showDebugInfo) { this.set(CommonParams.DEBUG_QUERY, String.valueOf(showDebugInfo)); } public SolrQuery setStart(Integer start) { if( start == null ) { this.remove( CommonParams.START ); } else { this.set(CommonParams.START, start); } return this; } public Integer getStart() { return this.getInt(CommonParams.START); } /** * Query type used to determine the request handler. * @see org.apache.solr.client.solrj.request.QueryRequest#getPath() * * @param qt Query Type that corresponds to the query request handler on the server. * @return this */ public SolrQuery setQueryType(String qt) { this.set(CommonParams.QT, qt); return this; } public String getQueryType() { return this.get(CommonParams.QT); } /** * @see ModifiableSolrParams#set(String,String[]) * @param name * @param values * * @return this */ public SolrQuery setParam(String name, String ... values) { this.set(name, values); return this; } /** * @see org.apache.solr.common.params.ModifiableSolrParams#set(String, boolean) * @param name * @param value * @return this */ public SolrQuery setParam(String name, boolean value) { this.set(name, value); return this; } /** get a deep copy of this object **/ public SolrQuery getCopy() { SolrQuery q = new SolrQuery(); for (String name : this.getParameterNames()) { q.setParam(name, this.getParams(name)); } return q; } /** * Set the maximum time allowed for this query. If the query takes more time * than the specified milliseconds, a timeout occurs and partial (or no) * results may be returned. * * If given Integer is null, then this parameter is removed from the request * *@param milliseconds the time in milliseconds allowed for this query */ public SolrQuery setTimeAllowed(Integer milliseconds) { if (milliseconds == null) { this.remove(CommonParams.TIME_ALLOWED); } else { this.set(CommonParams.TIME_ALLOWED, milliseconds); } return this; } /** * Get the maximum time allowed for this query. */ public Integer getTimeAllowed() { return this.getInt(CommonParams.TIME_ALLOWED); } /////////////////////// // Utility functions /////////////////////// private String toSortString(String field, ORDER order) { return field.trim() + ' ' + String.valueOf(order).trim(); } private String join(String a, String b, String sep) { StringBuilder sb = new StringBuilder(); if (a!=null && a.length()>0) { sb.append(a); sb.append(sep); } if (b!=null && b.length()>0) { sb.append(b); } return sb.toString().trim(); } private SolrQuery addValueToParam(String name, String value) { String tmp = this.get(name); tmp = join(tmp, value, ","); this.set(name, tmp); return this; } private String join(String[] vals, String sep, String removeVal) { StringBuilder sb = new StringBuilder(); for (int i=0; i<vals.length; i++) { if (removeVal==null || !vals[i].equals(removeVal)) { sb.append(vals[i]); if (i<vals.length-1) { sb.append(sep); } } } return sb.toString().trim(); } }