| /* |
| * 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 java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.regex.Pattern; |
| |
| 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.MoreLikeThisParams; |
| import org.apache.solr.common.params.StatsParams; |
| import org.apache.solr.common.params.TermsParams; |
| |
| |
| /** |
| * This is an augmented SolrParams with get/set/add fields for common fields used |
| * in the Standard and Dismax request handlers |
| * |
| * |
| * @since solr 1.3 |
| */ |
| public class SolrQuery extends ModifiableSolrParams |
| { |
| public static final String DOCID = "_docid_"; // duplicate of org.apache.solr.search.SortSpecParsing.DOCID which is not accessible from here |
| |
| public enum ORDER { desc, asc; |
| public ORDER reverse() { |
| return (this == asc) ? desc : asc; |
| } |
| } |
| |
| /** Maintains a map of current sorts */ |
| private List<SortClause> sortClauses; |
| |
| public SolrQuery() { |
| super(); |
| } |
| |
| /** Create a new SolrQuery |
| * |
| * @param q query string |
| */ |
| public SolrQuery(String q) { |
| this(); |
| this.set(CommonParams.Q, q); |
| } |
| |
| public SolrQuery(String k, String v, String... params) { |
| assert params.length % 2 == 0; |
| this.set(k, v); |
| for (int i = 0; i < params.length; i += 2) { |
| this.set(params[i], params[i + 1]); |
| } |
| } |
| |
| /** 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; |
| } |
| |
| /** Add field(s) for pivot computation. |
| * |
| * pivot fields are comma separated |
| * |
| * @param fields Array of field names from the IndexSchema |
| * @return this |
| */ |
| public SolrQuery addFacetPivotField(String ... fields) { |
| add(FacetParams.FACET_PIVOT, fields); |
| this.set(FacetParams.FACET, true); |
| return this; |
| } |
| |
| /** |
| * Add a numeric range facet. |
| * |
| * @param field The field |
| * @param start The start of range |
| * @param end The end of the range |
| * @param gap The gap between each count |
| * @return this |
| */ |
| public SolrQuery addNumericRangeFacet(String field, Number start, Number end, Number gap) { |
| add(FacetParams.FACET_RANGE, field); |
| add(String.format(Locale.ROOT, "f.%s.%s", field, FacetParams.FACET_RANGE_START), start.toString()); |
| add(String.format(Locale.ROOT, "f.%s.%s", field, FacetParams.FACET_RANGE_END), end.toString()); |
| add(String.format(Locale.ROOT, "f.%s.%s", field, FacetParams.FACET_RANGE_GAP), gap.toString()); |
| this.set(FacetParams.FACET, true); |
| return this; |
| } |
| |
| /** |
| * Add a numeric range facet. |
| * |
| * @param field The field |
| * @param start The start of range |
| * @param end The end of the range |
| * @param gap The gap between each count |
| * @return this |
| */ |
| public SolrQuery addDateRangeFacet(String field, Date start, Date end, String gap) { |
| add(FacetParams.FACET_RANGE, field); |
| add(String.format(Locale.ROOT, "f.%s.%s", field, FacetParams.FACET_RANGE_START), start.toInstant().toString()); |
| add(String.format(Locale.ROOT, "f.%s.%s", field, FacetParams.FACET_RANGE_END), end.toInstant().toString()); |
| add(String.format(Locale.ROOT, "f.%s.%s", field, FacetParams.FACET_RANGE_GAP), gap); |
| this.set(FacetParams.FACET, true); |
| return this; |
| } |
| |
| /** |
| * Add Interval Faceting on a field. All intervals for the same field should be included |
| * in the same call to this method. |
| * For syntax documentation see <a href="https://wiki.apache.org/solr/SimpleFacetParameters#Interval_Faceting">Solr wiki</a>. |
| * <br> |
| * Key substitution, filter exclusions or other local params on the field are not supported when using this method, |
| * if this is needed, use the lower level {@link #add} method.<br> |
| * Key substitution IS supported on intervals when using this method. |
| * |
| * |
| * @param field the field to add facet intervals. Must be an existing field and can't be null |
| * @param intervals Intervals to be used for faceting. It can be an empty array, but it can't |
| * be <code>null</code> |
| * @return this |
| */ |
| public SolrQuery addIntervalFacets(String field, String[] intervals) { |
| if (intervals == null) { |
| throw new IllegalArgumentException("Can't add null intervals"); |
| } |
| if (field == null) { |
| throw new IllegalArgumentException("Field can't be null"); |
| } |
| set(FacetParams.FACET, true); |
| add(FacetParams.FACET_INTERVAL, field); |
| for (String interval:intervals) { |
| add(String.format(Locale.ROOT, "f.%s.facet.interval.set", field), interval); |
| } |
| return this; |
| } |
| |
| /** |
| * Remove all Interval Facets on a field |
| * |
| * @param field the field to remove from facet intervals |
| * @return Array of current intervals for <code>field</code> |
| */ |
| public String[] removeIntervalFacets(String field) { |
| while(remove(FacetParams.FACET_INTERVAL, field)){}; |
| return remove(String.format(Locale.ROOT, "f.%s.facet.interval.set", field)); |
| } |
| |
| /** 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... |
| this.remove(FacetParams.FACET_INTERVAL); // does not remove interval parameters |
| } |
| 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); |
| this.set(FacetParams.FACET, true); |
| 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; |
| } |
| |
| /** 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); |
| } |
| |
| |
| /** set facet sort |
| * |
| * @param sort sort facets |
| * @return this |
| */ |
| public SolrQuery setFacetSort(String sort) { |
| this.set(FacetParams.FACET_SORT, sort); |
| 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, ""); |
| } |
| |
| /** |
| * Gets the raw sort field, as it will be sent to Solr. |
| * <p> |
| * The returned sort field will always contain a serialized version |
| * of the sort string built using {@link #setSort(SortClause)}, |
| * {@link #addSort(SortClause)}, {@link #addOrUpdateSort(SortClause)}, |
| * {@link #removeSort(SortClause)}, {@link #clearSorts()} and |
| * {@link #setSorts(List)}. |
| */ |
| public String getSortField() { |
| return this.get(CommonParams.SORT); |
| } |
| |
| /** |
| * Clears current sort information. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery clearSorts() { |
| sortClauses = null; |
| serializeSorts(); |
| return this; |
| } |
| |
| /** |
| * Replaces the current sort information. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery setSorts(List<SortClause> value) { |
| sortClauses = new ArrayList<>(value); |
| serializeSorts(); |
| return this; |
| } |
| |
| /** |
| * Gets an a list of current sort clauses. |
| * |
| * @return an immutable list of current sort clauses |
| * @since 4.2 |
| */ |
| public List<SortClause> getSorts() { |
| if (sortClauses == null) return Collections.emptyList(); |
| else return Collections.unmodifiableList(sortClauses); |
| } |
| |
| /** |
| * Replaces the current sort information with a single sort clause |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery setSort(String field, ORDER order) { |
| return setSort(new SortClause(field, order)); |
| } |
| |
| /** |
| * Replaces the current sort information with a single sort clause |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery setSort(SortClause sortClause) { |
| clearSorts(); |
| return addSort(sortClause); |
| } |
| |
| /** |
| * Adds a single sort clause to the end of the current sort information. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery addSort(String field, ORDER order) { |
| return addSort(new SortClause(field, order)); |
| } |
| |
| /** |
| * Adds a single sort clause to the end of the query. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery addSort(SortClause sortClause) { |
| if (sortClauses == null) sortClauses = new ArrayList<>(); |
| sortClauses.add(sortClause); |
| serializeSorts(); |
| return this; |
| } |
| |
| /** |
| * Updates or adds a single sort clause to the query. |
| * If the field is already used for sorting, the order |
| * of the existing field is modified; otherwise, it is |
| * added to the end. |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery addOrUpdateSort(String field, ORDER order) { |
| return addOrUpdateSort(new SortClause(field, order)); |
| } |
| |
| /** |
| * Updates or adds a single sort field specification to the current sort |
| * information. If the sort field already exist in the sort information map, |
| * its position is unchanged and the sort order is set; if it does not exist, |
| * it is appended at the end with the specified order.. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery addOrUpdateSort(SortClause sortClause) { |
| if (sortClauses != null) { |
| for (int index=0 ; index<sortClauses.size() ; index++) { |
| SortClause existing = sortClauses.get(index); |
| if (existing.getItem().equals(sortClause.getItem())) { |
| sortClauses.set(index, sortClause); |
| serializeSorts(); |
| return this; |
| } |
| } |
| } |
| return addSort(sortClause); |
| } |
| |
| /** |
| * Removes a single sort field from the current sort information. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery removeSort(SortClause sortClause) { |
| return removeSort(sortClause.getItem()); |
| } |
| |
| /** |
| * Removes a single sort field from the current sort information. |
| * |
| * @return the modified SolrQuery object, for easy chaining |
| * @since 4.2 |
| */ |
| public SolrQuery removeSort(String itemName) { |
| if (sortClauses != null) { |
| for (SortClause existing : sortClauses) { |
| if (existing.getItem().equals(itemName)) { |
| sortClauses.remove(existing); |
| if (sortClauses.isEmpty()) sortClauses = null; |
| serializeSorts(); |
| break; |
| } |
| } |
| } |
| return this; |
| } |
| |
| private void serializeSorts() { |
| if (sortClauses == null || sortClauses.isEmpty()) { |
| remove(CommonParams.SORT); |
| } else { |
| StringBuilder sb = new StringBuilder(); |
| for (SortClause sortClause : sortClauses) { |
| if (sb.length() > 0) sb.append(","); |
| sb.append(sortClause.getItem()); |
| sb.append(" "); |
| sb.append(sortClause.getOrder()); |
| } |
| set(CommonParams.SORT, sb.toString()); |
| } |
| } |
| |
| 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 addGetFieldStatistics( 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 void addStatsFieldCalcDistinct(String field, boolean calcDistinct) { |
| if (field == null) { |
| this.add(StatsParams.STATS_CALC_DISTINCT, Boolean.toString(calcDistinct)); |
| } else { |
| this.add("f." + field + "." + StatsParams.STATS_CALC_DISTINCT, Boolean.toString(calcDistinct)); |
| } |
| } |
| |
| 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; |
| } |
| |
| |
| /** |
| * Add field for MoreLikeThis. Automatically |
| * enables MoreLikeThis. |
| * |
| * @param field the names of the field to be added |
| * @return this |
| */ |
| public SolrQuery addMoreLikeThisField(String field) { |
| this.setMoreLikeThis(true); |
| return addValueToParam(MoreLikeThisParams.SIMILARITY_FIELDS, field); |
| } |
| |
| public SolrQuery setMoreLikeThisFields(String... fields) { |
| if( fields == null || fields.length == 0 ) { |
| this.remove( MoreLikeThisParams.SIMILARITY_FIELDS ); |
| this.setMoreLikeThis(false); |
| 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(MoreLikeThisParams.SIMILARITY_FIELDS, sb.toString()); |
| this.setMoreLikeThis(true); |
| return this; |
| } |
| |
| /** |
| * @return an array with the fields used to compute similarity. |
| */ |
| public String[] getMoreLikeThisFields() { |
| String fl = this.get(MoreLikeThisParams.SIMILARITY_FIELDS); |
| if(fl==null || fl.length()==0) { |
| return null; |
| } |
| return fl.split(","); |
| } |
| |
| /** |
| * Sets the frequency below which terms will be ignored in the source doc |
| * |
| * @param mintf the minimum term frequency |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisMinTermFreq(int mintf) { |
| this.set(MoreLikeThisParams.MIN_TERM_FREQ, mintf); |
| return this; |
| } |
| |
| /** |
| * Gets the frequency below which terms will be ignored in the source doc |
| */ |
| public int getMoreLikeThisMinTermFreq() { |
| return this.getInt(MoreLikeThisParams.MIN_TERM_FREQ, 2); |
| } |
| |
| /** |
| * Sets the frequency at which words will be ignored which do not occur in |
| * at least this many docs. |
| * |
| * @param mindf the minimum document frequency |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisMinDocFreq(int mindf) { |
| this.set(MoreLikeThisParams.MIN_DOC_FREQ, mindf); |
| return this; |
| } |
| |
| /** |
| * Gets the frequency at which words will be ignored which do not occur in |
| * at least this many docs. |
| */ |
| public int getMoreLikeThisMinDocFreq() { |
| return this.getInt(MoreLikeThisParams.MIN_DOC_FREQ, 5); |
| } |
| |
| /** |
| * Sets the minimum word length below which words will be ignored. |
| * |
| * @param minwl the minimum word length |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisMinWordLen(int minwl) { |
| this.set(MoreLikeThisParams.MIN_WORD_LEN, minwl); |
| return this; |
| } |
| |
| /** |
| * Gets the minimum word length below which words will be ignored. |
| */ |
| public int getMoreLikeThisMinWordLen() { |
| return this.getInt(MoreLikeThisParams.MIN_WORD_LEN, 0); |
| } |
| |
| /** |
| * Sets the maximum word length above which words will be ignored. |
| * |
| * @param maxwl the maximum word length |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisMaxWordLen(int maxwl) { |
| this.set(MoreLikeThisParams.MAX_WORD_LEN, maxwl); |
| return this; |
| } |
| |
| /** |
| * Gets the maximum word length above which words will be ignored. |
| */ |
| public int getMoreLikeThisMaxWordLen() { |
| return this.getInt(MoreLikeThisParams.MAX_WORD_LEN, 0); |
| } |
| |
| /** |
| * Sets the maximum number of query terms that will be included in any |
| * generated query. |
| * |
| * @param maxqt the maximum number of query terms |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisMaxQueryTerms(int maxqt) { |
| this.set(MoreLikeThisParams.MAX_QUERY_TERMS, maxqt); |
| return this; |
| } |
| |
| /** |
| * Gets the maximum number of query terms that will be included in any |
| * generated query. |
| */ |
| public int getMoreLikeThisMaxQueryTerms() { |
| return this.getInt(MoreLikeThisParams.MAX_QUERY_TERMS, 25); |
| } |
| |
| /** |
| * Sets the maximum number of tokens to parse in each example doc field |
| * that is not stored with TermVector support. |
| * |
| * @param maxntp the maximum number of tokens to parse |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisMaxTokensParsed(int maxntp) { |
| this.set(MoreLikeThisParams.MAX_NUM_TOKENS_PARSED, maxntp); |
| return this; |
| } |
| |
| /** |
| * Gets the maximum number of tokens to parse in each example doc field |
| * that is not stored with TermVector support. |
| */ |
| public int getMoreLikeThisMaxTokensParsed() { |
| return this.getInt(MoreLikeThisParams.MAX_NUM_TOKENS_PARSED, 5000); |
| } |
| |
| /** |
| * Sets if the query will be boosted by the interesting term relevance. |
| * |
| * @param b set to true to boost the query with the interesting term relevance |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisBoost(boolean b) { |
| this.set(MoreLikeThisParams.BOOST, b); |
| return this; |
| } |
| |
| /** |
| * Gets if the query will be boosted by the interesting term relevance. |
| */ |
| public boolean getMoreLikeThisBoost() { |
| return this.getBool(MoreLikeThisParams.BOOST, false); |
| } |
| |
| /** |
| * Sets the query fields and their boosts using the same format as that |
| * used in DisMaxQParserPlugin. These fields must also be added |
| * using {@link #addMoreLikeThisField(String)}. |
| * |
| * @param qf the query fields |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisQF(String qf) { |
| this.set(MoreLikeThisParams.QF, qf); |
| return this; |
| } |
| |
| /** |
| * Gets the query fields and their boosts. |
| */ |
| public String getMoreLikeThisQF() { |
| return this.get(MoreLikeThisParams.QF); |
| } |
| |
| /** |
| * Sets the number of similar documents to return for each result. |
| * |
| * @param count the number of similar documents to return for each result |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThisCount(int count) { |
| this.set(MoreLikeThisParams.DOC_COUNT, count); |
| return this; |
| } |
| |
| /** |
| * Gets the number of similar documents to return for each result. |
| */ |
| public int getMoreLikeThisCount() { |
| return this.getInt(MoreLikeThisParams.DOC_COUNT, MoreLikeThisParams.DEFAULT_DOC_COUNT); |
| } |
| |
| /** |
| * Enable/Disable MoreLikeThis. After enabling MoreLikeThis, the fields |
| * used for computing similarity must be specified calling |
| * {@link #addMoreLikeThisField(String)}. |
| * |
| * @param b flag to indicate if MoreLikeThis should be enabled. if b==false |
| * removes all mlt.* parameters |
| * @return this |
| */ |
| public SolrQuery setMoreLikeThis(boolean b) { |
| if(b) { |
| this.set(MoreLikeThisParams.MLT, true); |
| } else { |
| this.remove(MoreLikeThisParams.MLT); |
| this.remove(MoreLikeThisParams.SIMILARITY_FIELDS); |
| this.remove(MoreLikeThisParams.MIN_TERM_FREQ); |
| this.remove(MoreLikeThisParams.MIN_DOC_FREQ); |
| this.remove(MoreLikeThisParams.MIN_WORD_LEN); |
| this.remove(MoreLikeThisParams.MAX_WORD_LEN); |
| this.remove(MoreLikeThisParams.MAX_QUERY_TERMS); |
| this.remove(MoreLikeThisParams.MAX_NUM_TOKENS_PARSED); |
| this.remove(MoreLikeThisParams.BOOST); |
| this.remove(MoreLikeThisParams.QF); |
| this.remove(MoreLikeThisParams.DOC_COUNT); |
| } |
| return this; |
| } |
| |
| /** |
| * @return true if MoreLikeThis is enabled, false otherwise |
| */ |
| public boolean getMoreLikeThis() { |
| return this.getBool(MoreLikeThisParams.MLT, false); |
| } |
| |
| 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 SolrQuery setShowDebugInfo(boolean showDebugInfo) { |
| this.set(CommonParams.DEBUG_QUERY, String.valueOf(showDebugInfo)); |
| return this; |
| } |
| |
| public void setDistrib(boolean val) { |
| this.set(CommonParams.DISTRIB, String.valueOf(val)); |
| } |
| |
| |
| 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); |
| } |
| |
| /** |
| * The Request Handler to use (see the solrconfig.xml), which is stored in the "qt" parameter. |
| * Normally it starts with a '/' and if so it will be used by |
| * {@link org.apache.solr.client.solrj.request.QueryRequest#getPath()} in the URL instead of the "qt" parameter. |
| * If this is left blank, then the default of "/select" is assumed. |
| * |
| * @param qt The Request Handler name corresponding to one in solrconfig.xml on the server. |
| * @return this |
| */ |
| public SolrQuery setRequestHandler(String qt) { |
| this.set(CommonParams.QT, qt); |
| return this; |
| } |
| |
| public String getRequestHandler() { |
| return this.get(CommonParams.QT); |
| } |
| |
| /** |
| * @return this |
| * @see ModifiableSolrParams#set(String,String[]) |
| */ |
| public SolrQuery setParam(String name, String ... values) { |
| this.set(name, values); |
| return this; |
| } |
| |
| /** |
| * @return this |
| * @see org.apache.solr.common.params.ModifiableSolrParams#set(String, boolean) |
| */ |
| 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 (!vals[i].equals(removeVal)) { |
| if (sb.length() > 0) { |
| sb.append(sep); |
| } |
| sb.append(vals[i]); |
| } |
| } |
| return sb.toString().trim(); |
| } |
| |
| /** |
| * A single sort clause, encapsulating what to sort and the sort order. |
| * <p> |
| * The item specified can be "anything sortable" by solr; some examples |
| * include a simple field name, the constant string {@code score}, and functions |
| * such as {@code sum(x_f, y_f)}. |
| * <p> |
| * A SortClause can be created through different mechanisms: |
| * <PRE><code> |
| * new SortClause("product", SolrQuery.ORDER.asc); |
| * new SortClause("product", "asc"); |
| * SortClause.asc("product"); |
| * SortClause.desc("product"); |
| * </code></PRE> |
| */ |
| public static class SortClause implements java.io.Serializable { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private final String item; |
| private final ORDER order; |
| |
| /** |
| * Creates a SortClause based on item and order |
| * @param item item to sort on |
| * @param order direction to sort |
| */ |
| public SortClause(String item, ORDER order) { |
| this.item = item; |
| this.order = order; |
| } |
| |
| /** |
| * Creates a SortClause based on item and order |
| * @param item item to sort on |
| * @param order string value for direction to sort |
| */ |
| public SortClause(String item, String order) { |
| this(item, ORDER.valueOf(order)); |
| } |
| |
| /** |
| * Creates an ascending SortClause for an item |
| * @param item item to sort on |
| */ |
| public static SortClause create (String item, ORDER order) { |
| return new SortClause(item, order); |
| } |
| |
| /** |
| * Creates a SortClause based on item and order |
| * @param item item to sort on |
| * @param order string value for direction to sort |
| */ |
| public static SortClause create(String item, String order) { |
| return new SortClause(item, ORDER.valueOf(order)); |
| } |
| |
| /** |
| * Creates an ascending SortClause for an item |
| * @param item item to sort on |
| */ |
| public static SortClause asc (String item) { |
| return new SortClause(item, ORDER.asc); |
| } |
| |
| /** |
| * Creates a decending SortClause for an item |
| * @param item item to sort on |
| */ |
| public static SortClause desc (String item) { |
| return new SortClause(item, ORDER.desc); |
| } |
| |
| /** |
| * Gets the item to sort, typically a function or a fieldname |
| * @return item to sort |
| */ |
| public String getItem() { |
| return item; |
| } |
| |
| /** |
| * Gets the order to sort |
| * @return order to sort |
| */ |
| public ORDER getOrder() { |
| return order; |
| } |
| |
| public boolean equals(Object other){ |
| if (this == other) return true; |
| if (!(other instanceof SortClause)) return false; |
| final SortClause that = (SortClause) other; |
| return this.getItem().equals(that.getItem()) && this.getOrder().equals(that.getOrder()); |
| } |
| |
| public int hashCode(){ |
| return this.getItem().hashCode(); |
| } |
| |
| /** |
| * Gets a human readable description of the sort clause. |
| * <p> |
| * The returned string is not suitable for passing to Solr, |
| * but may be useful in debug output and the like. |
| * @return a description of the current sort clause |
| */ |
| public String toString() { |
| return "[" + getClass().getSimpleName() + ": item=" + getItem() + "; order=" + getOrder() + "]"; |
| } |
| } |
| } |