package org.apache.solr.search; import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException; import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler; import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys; import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator; import org.apache.lucene.queryparser.flexible.aqp.AqpQueryParser; import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardLuceneParser; import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryConfigHandler; import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryNodeProcessorPipeline; import org.apache.lucene.queryparser.flexible.aqp.parser.AqpStandardQueryTreeBuilder; import org.apache.lucene.search.Query; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.schema.IndexSchema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is the MAIN solr entry point - this instantiates a query * parser - it sets some default parameters from the config and prepares * ulr parameters. * * <p> * * TODO: the parser needs to know configuration of data/numeric fields * so that the analysis is done correctly. It is not done here * for the moment (as this is SOLR-specific and needs more * components) * <p> * In principle, it is configured like this: * * <pre> * HashMap<String, NumericConfig> ncm = new HashMap<String, NumericConfig>(); * config.set(StandardQueryConfigHandler.ConfigurationKeys.NUMERIC_CONFIG_MAP, ncm); * ncm.put(field_name, new NumericConfig(4, NumberFormat.getNumberInstance(Locale.US), NumericType.INT)); * </pre> * * @see AqpLuceneQParserPlugin * @see AqpStandardLuceneParser * @see AqpStandardQueryConfigHandler * @see AqpStandardQueryNodeProcessorPipeline * @see AqpStandardQueryTreeBuilder * */ public class AqpLuceneQParser extends QParser { public static final Logger log = LoggerFactory .getLogger(AqpLuceneQParser.class); private AqpQueryParser qParser; public AqpLuceneQParser(AqpQueryParser parser, String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) throws QueryNodeParseException { super(qstr, localParams, params, req); qParser = parser; if (getString() == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "The query is empty"); } IndexSchema schema = req.getSchema(); // now configure the parser using the request params, likely incomplete (yet) QueryConfigHandler config = qParser.getQueryConfigHandler(); qParser.setAnalyzer(schema.getQueryAnalyzer()); //CHECK: this used to be getAnalyzer(); potentially dangerous qParser.setDefaultField(params.get(CommonParams.DF, qParser.getDefaultField())); String opParam = getParam(QueryParsing.OP); if (opParam != null) { // other operators could also become default, eg. NEAR qParser.setDefaultOperator("AND".equals(opParam.toUpperCase()) ? Operator.AND : Operator.OR); } else { qParser.setDefaultOperator(Operator.OR); } // this is not useful in solr world (?) - but must be available config.set(ConfigurationKeys.MULTI_FIELDS, new CharSequence[0]); if (params.getBool("debugQuery", false) != false) { try { qParser.setDebug(true); } catch (Exception e) { e.printStackTrace(); } } // your components may need access to solr, if there is some 'semantic analysis' // involved, eg. multi-step parsing of a query. I do it this way (the component // may be committed to solr in other tickets) // AqpRequestParams reqAttr = config.get(AqpAdsabsQueryConfigHandler.ConfigurationKeys.SOLR_REQUEST); // reqAttr.setQueryString(getString()); // reqAttr.setRequest(req); // reqAttr.setLocalParams(localParams); // reqAttr.setParams(params); } @Override public Query parse() throws SyntaxError { try { return qParser.parse(getString(), null); } catch (QueryNodeException e) { throw new SyntaxError(e.getMessage(), e); } catch (SolrException e1) { throw new SyntaxError(e1.getMessage(), e1); } } public AqpQueryParser getParser() { return qParser; } }