001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.solr.request;
017:
018: import org.apache.lucene.search.*;
019:
020: import java.net.MalformedURLException;
021: import java.net.URL;
022: import java.util.ArrayList;
023: import java.util.List;
024:
025: import org.apache.solr.util.StrUtils;
026: import org.apache.solr.util.NamedList;
027: import org.apache.solr.util.HighlightingUtils;
028: import org.apache.solr.util.SolrPluginUtils;
029: import org.apache.solr.search.*;
030: import org.apache.solr.core.SolrCore;
031: import org.apache.solr.core.SolrException;
032: import org.apache.solr.handler.RequestHandlerBase;
033:
034: import static org.apache.solr.request.SolrParams.*;
035:
036: /**
037: * @author yonik
038: * @version $Id: StandardRequestHandler.java 542679 2007-05-29 22:28:21Z ryan $
039: *
040: * All of the following options may be configured for this handler
041: * in the solrconfig as defaults, and may be overriden as request parameters.
042: * (TODO: complete documentation of request parameters here, rather than only
043: * on the wiki).
044: * </p>
045: *
046: * <ul>
047: * <li> highlight - Set to any value not .equal() to "false" to enable highlight
048: * generation</li>
049: * <li> highlightFields - Set to a comma- or space-delimited list of fields to
050: * highlight. If unspecified, uses the default query field</li>
051: * <li> maxSnippets - maximum number of snippets to generate per field-highlight.
052: * </li>
053: * </ul>
054: *
055: */
056: public class StandardRequestHandler extends RequestHandlerBase {
057:
058: /** shorten the class references for utilities */
059: private static class U extends SolrPluginUtils {
060: /* :NOOP */
061: }
062:
063: public void handleRequestBody(SolrQueryRequest req,
064: SolrQueryResponse rsp) throws Exception {
065:
066: SolrParams p = req.getParams();
067: String qstr = p.required().get(Q);
068:
069: String defaultField = p.get(DF);
070:
071: // find fieldnames to return (fieldlist)
072: String fl = p.get(SolrParams.FL);
073: int flags = 0;
074: if (fl != null) {
075: flags |= U.setReturnFields(fl, rsp);
076: }
077:
078: String sortStr = p.get(SORT);
079: if (sortStr == null) {
080: // TODO? should we disable the ';' syntax with config?
081: // legacy mode, where sreq is query;sort
082: List<String> commands = StrUtils.splitSmart(qstr, ';');
083: if (commands.size() == 2) {
084: // TODO? add a deprication warning to the response header
085: qstr = commands.get(0);
086: sortStr = commands.get(1);
087: } else if (commands.size() == 1) {
088: // This is need to support the case where someone sends: "q=query;"
089: qstr = commands.get(0);
090: } else if (commands.size() > 2) {
091: throw new SolrException(
092: SolrException.ErrorCode.BAD_REQUEST,
093: "If you want to use multiple ';' in the query, use the 'sort' param.");
094: }
095: }
096:
097: Sort sort = null;
098: if (sortStr != null) {
099: QueryParsing.SortSpec sortSpec = QueryParsing.parseSort(
100: sortStr, req.getSchema());
101: if (sortSpec != null) {
102: sort = sortSpec.getSort();
103: }
104: }
105:
106: // parse the query from the 'q' parameter (sort has been striped)
107: Query query = QueryParsing.parseQuery(qstr, defaultField, p,
108: req.getSchema());
109:
110: DocListAndSet results = new DocListAndSet();
111: NamedList facetInfo = null;
112: List<Query> filters = U.parseFilterQueries(req);
113: SolrIndexSearcher s = req.getSearcher();
114:
115: if (p.getBool(FACET, false)) {
116: results = s.getDocListAndSet(query, filters, sort, p
117: .getInt(START, 0), p.getInt(ROWS, 10), flags);
118: facetInfo = getFacetInfo(req, rsp, results.docSet);
119: } else {
120: results.docList = s.getDocList(query, filters, sort, p
121: .getInt(START, 0), p.getInt(ROWS, 10), flags);
122: }
123:
124: // pre-fetch returned documents
125: U.optimizePreFetchDocs(results.docList, query, req, rsp);
126:
127: rsp.add("response", results.docList);
128:
129: if (null != facetInfo)
130: rsp.add("facet_counts", facetInfo);
131:
132: try {
133: NamedList dbg = U.doStandardDebug(req, qstr, query,
134: results.docList);
135: if (null != dbg) {
136: if (null != filters) {
137: dbg.add("filter_queries", req.getParams()
138: .getParams(FQ));
139: List<String> fqs = new ArrayList<String>(filters
140: .size());
141: for (Query fq : filters) {
142: fqs.add(QueryParsing.toString(fq, req
143: .getSchema()));
144: }
145: dbg.add("parsed_filter_queries", fqs);
146: }
147: rsp.add("debug", dbg);
148: }
149: } catch (Exception e) {
150: SolrException.logOnce(SolrCore.log,
151: "Exception during debug", e);
152: rsp.add("exception_during_debug", SolrException.toStr(e));
153: }
154:
155: NamedList sumData = HighlightingUtils.doHighlighting(
156: results.docList, query.rewrite(req.getSearcher()
157: .getReader()), req,
158: new String[] { defaultField });
159: if (sumData != null)
160: rsp.add("highlighting", sumData);
161: }
162:
163: /**
164: * Fetches information about Facets for this request.
165: *
166: * Subclasses may with to override this method to provide more
167: * advanced faceting behavior.
168: * @see SimpleFacets#getFacetCounts
169: */
170: protected NamedList getFacetInfo(SolrQueryRequest req,
171: SolrQueryResponse rsp, DocSet mainSet) {
172:
173: SimpleFacets f = new SimpleFacets(req.getSearcher(), mainSet,
174: req.getParams());
175: return f.getFacetCounts();
176: }
177:
178: //////////////////////// SolrInfoMBeans methods //////////////////////
179:
180: public String getVersion() {
181: return "$Revision: 542679 $";
182: }
183:
184: public String getDescription() {
185: return "The standard Solr request handler";
186: }
187:
188: public String getSourceId() {
189: return "$Id: StandardRequestHandler.java 542679 2007-05-29 22:28:21Z ryan $";
190: }
191:
192: public String getSource() {
193: return "$URL: https://svn.apache.org/repos/asf/lucene/solr/branches/branch-1.2/src/java/org/apache/solr/request/StandardRequestHandler.java $";
194: }
195:
196: public URL[] getDocs() {
197: try {
198: return new URL[] { new URL(
199: "http://wiki.apache.org/solr/StandardRequestHandler") };
200: } catch (MalformedURLException ex) {
201: return null;
202: }
203: }
204: }
|