package org.apache.solr.search; /* * 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. */ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.spans.SpanQueryParser; import org.apache.lucene.search.MultiTermQuery.RewriteMethod; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; import org.apache.solr.schema.TextField; /** * Overrides features of Lucene's SpanQueryParser to enable * pulling the correct analyzer for each field and for * handling non-analyzed fields. * <p> * This also allows Solr non-text fields to parse the * appropriate components of the query string. * <p> * The process could be simpler, but this returns a null analyzer * if the field is not text and/or has a null analyzer. The SpanQueryParser * then calls the "handleNullAnalyzer..." functions when it gets a null analyzer. */ public class SolrSpanQueryParser extends SpanQueryParser { private final IndexSchema schema; //parser to use for fields that have a null analyzer private final QParser nonTextParser; // private static Logger log = LoggerFactory.getLogger(SolrCore.class); public SolrSpanQueryParser(String f, Analyzer a, IndexSchema schema, QParser nonTextParser) { super(f, a, null); this.schema = schema; this.nonTextParser = nonTextParser; } @Override public Query handleNullAnalyzerRange(String fieldName, String start, String end, boolean startInclusive, boolean endInclusive) { //lifted from SolrQueryParserBase SchemaField sf = schema.getFieldOrNull(fieldName); if (sf != null) { FieldType ft = sf.getType(); return ft.getRangeQuery(nonTextParser, sf, start, end, startInclusive, endInclusive); } //if sf == null, back off to raw terms as ranges return super.handleNullAnalyzerRange(fieldName, start, end, startInclusive, endInclusive); } @Override public Query handleNullAnalyzer(String fieldName, String queryText) { //lifted from SolrQueryParserBase SchemaField sf = schema.getFieldOrNull(fieldName); if (sf != null) { return sf.getType().getFieldQuery(nonTextParser, sf, queryText); } return new TermQuery(new Term(fieldName, queryText)); } @Override public Query handleNullAnalyzerPrefix(String fieldName, String prefix) { //by the time you're here, you know that the analyzer was null and/or //this isn't a TextField SchemaField sf = schema.getFieldOrNull(fieldName); if (sf == null) { return new TermQuery(new Term(fieldName, prefix)); } return sf.getType().getPrefixQuery(nonTextParser, sf, prefix); } /** * Returns analyzer to be used on full terms within a field. * * @param fieldName field name * @return analyzer to use on a requested field for whole terms. Returns getAnalyzer() if * field is not found in wholeTermAnalyzers. */ @Override public Analyzer getAnalyzer(String fieldName) { SchemaField field = schema.getFieldOrNull(fieldName); if (field == null) { return null; } FieldType type = field.getType(); if (type instanceof TextField) { return ((TextField) type).getQueryAnalyzer(); } return null; } /** * Returns the multiterm analyzer to be used on a specific field. * Override to modify behavior. * * @param fieldName field name * @return analyzer to use on a requested field for multiTerm terms. Returns getMultiTermAnalyzer() * if field is not found in multiTermAnalyzers */ @Override public Analyzer getMultiTermAnalyzer(String fieldName) { SchemaField field = schema.getFieldOrNull(fieldName); if (field == null) { return null; } FieldType type = field.getType(); if (type instanceof TextField) { return ((TextField) type).getMultiTermAnalyzer(); } return null; } /** * @param fieldName field name * @return RewriteMethod for a given field */ @Override public RewriteMethod getMultiTermRewriteMethod(String fieldName) { SchemaField field = schema.getFieldOrNull(fieldName); if (field == null) { return getMultiTermRewriteMethod(); } FieldType type = field.getType(); return type.getRewriteMethod(nonTextParser, field); } }