/** * This software is licensed to you under the Apache License, Version 2.0 (the * "Apache License"). * * LinkedIn's contributions are made under the Apache License. If you contribute * to the Software, the contributions will be deemed to have been made under the * Apache License, unless you expressly indicate otherwise. Please do not make any * contributions that would be inconsistent with the Apache License. * * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, this software * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache * License for the specific language governing permissions and limitations for the * software governed under the Apache License. * * © 2012 LinkedIn Corp. All Rights Reserved. */ package com.senseidb.search.query; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.Query; import org.json.JSONException; import org.json.JSONObject; import com.senseidb.search.query.ScoreAugmentQuery.ScoreAugmentFunction; import com.senseidb.search.relevance.RelevanceFunctionBuilder; import com.senseidb.search.relevance.impl.RelevanceJSONConstants; public abstract class QueryConstructor { public static final String VALUES_PARAM = "values"; public static final String EXCLUDES_PARAM = "excludes"; public static final String OPERATOR_PARAM = "operator"; public static final String PARAMS_PARAM = "params"; public static final String MUST_PARAM = "must"; public static final String MUST_NOT_PARAM = "must_not"; public static final String SHOULD_PARAM = "should"; public static final String BOOST_PARAM = "boost"; public static final String DISABLE_COORD_PARAM = "disable_coord"; public static final String MINIMUM_NUMBER_SHOULD_MATCH_PARAM = "minimum_number_should_match"; public static final String TYPE_PARAM = "type"; public static final String PHRASE_PARAM = "phrase"; public static final String PHRASE_PREFIX_PARAM = "phrase_prefix"; public static final String AND_PARAM = "and"; public static final String INCLUDE_PARAM = "include"; public static final String EXCLUDE_PARAM = "exclude"; public static final String SPAN_TERM_PARAM = "span_term"; public static final String MATCH_PARAM = "match"; public static final String END_PARAM = "end"; public static final String CLASS_PARAM = "class"; public static final String MINIMUM_MATCH_PARAM = "minimum_match"; public static final String CLAUSES_PARAM = "clauses"; public static final String SLOP_PARAM = "slop"; public static final String IN_ORDER_PARAM = "in_order"; public static final String COLLECT_PAYLOADS_PARAM = "collect_payloads"; public static final String VALUE_PARAM = "value"; public static final String QUERY_PARAM = "query"; public static final String FILTER_PARAM = "filter"; public static final String QUERIES_PARAM = "queries"; public static final String TERM_PARAM = "term"; public static final String TIE_BREAKER_PARAM = "tie_breaker"; public static final String DEFAULT_FIELD_PARAM = "default_field"; public static final String FIELDS_PARAM = "fields"; public static final String DEFAULT_OPERATOR_PARAM = "default_operator"; public static final String ALLOW_LEADING_WILDCARD_PARAM = "allow_leading_wildcard"; public static final String LOWERCASE_EXPANDED_TERMS_PARAM = "lowercase_expanded_terms"; public static final String ENABLE_POSITION_INCREMENTS_PARAM = "enable_position_increments"; public static final String FUZZY_PREFIX_LENGTH_PARAM = "fuzzy_prefix_length"; public static final String FUZZY_MIN_SIM_PARAM = "fuzzy_min_sim"; public static final String PHRASE_SLOP_PARAM = "phrase_slop"; public static final String ANALYZE_WILDCARD_PARAM = "analyze_wildcard"; public static final String AUTO_GENERATE_PHRASE_QUERIES_PARAM = "auto_generate_phrase_queries"; public static final String USE_DIS_MAX_PARAM = "use_dis_max"; public static final String RELEVANCE = "relevance"; public static final String LEFT_VALUE = "lvalue"; public static final String RIGHT_VALUE = "rvalue"; public static final String OP_IN = "in"; public static final String OP_NOT_IN = "not_in"; public static final String OP_GT = ">"; public static final String OP_GE = ">="; public static final String OP_EQUAL = "=="; public static final String OP_NOT_EQUAL = "!="; public static final String OP_LT = "<"; public static final String OP_LE = "<="; public static final String FUNCTION_NAME = "function"; private static final Map<String,QueryConstructor> QUERY_CONSTRUCTOR_MAP = new HashMap<String,QueryConstructor>(); static { QUERY_CONSTRUCTOR_MAP.put(DistMaxQueryConstructor.QUERY_TYPE, new DistMaxQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(PrefixQueryConstructor.QUERY_TYPE, new PrefixQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(WildcardQueryConstructor.QUERY_TYPE, new WildcardQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(RangeQueryConstructor.QUERY_TYPE, new RangeQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(PathQueryConstructor.QUERY_TYPE, new PathQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(SpanFirstQueryConstructor.QUERY_TYPE, new SpanFirstQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(SpanNearQueryConstructor.QUERY_TYPE, new SpanNearQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(SpanNotQueryConstructor.QUERY_TYPE, new SpanNotQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(SpanOrQueryConstructor.QUERY_TYPE, new SpanOrQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(SpanTermQueryConstructor.QUERY_TYPE, new SpanTermQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(MatchAllQueryConstructor.QUERY_TYPE, new MatchAllQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(TermQueryConstructor.QUERY_TYPE, new TermQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(TermsQueryConstructor.QUERY_TYPE, new TermsQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(UIDQueryConstructor.QUERY_TYPE, new UIDQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(CustomQueryConstructor.QUERY_TYPE, new CustomQueryConstructor()); QUERY_CONSTRUCTOR_MAP.put(ConstExpQueryConstructor.QUERY_TYPE, new ConstExpQueryConstructor()); } public static QueryConstructor getQueryConstructor(String type, QueryParser qparser) { QueryConstructor queryConstructor = QUERY_CONSTRUCTOR_MAP.get(type); if (queryConstructor == null) { if (QueryStringQueryConstructor.QUERY_TYPE.equals(type)) queryConstructor = new QueryStringQueryConstructor(qparser); else if (TextQueryConstructor.QUERY_TYPE.equals(type)) queryConstructor = new TextQueryConstructor(qparser); else if (BooleanQueryConstructor.QUERY_TYPE.equals(type)) queryConstructor = new BooleanQueryConstructor(qparser); else if (FilteredQueryConstructor.QUERY_TYPE.equals(type)) queryConstructor = new FilteredQueryConstructor(qparser); } return queryConstructor; } public static Query constructQuery(JSONObject jsonQuery, QueryParser qparser) throws JSONException { if (jsonQuery == null) return null; Iterator<String> iter = jsonQuery.keys(); if (!iter.hasNext()) return null; String type = iter.next(); QueryConstructor queryConstructor = QueryConstructor.getQueryConstructor(type, qparser); if (queryConstructor == null) throw new IllegalArgumentException("Query type '" + type + "' not supported"); JSONObject jsonValue = jsonQuery.getJSONObject(type); Query baseQuery = null; if (type.equals(CustomQueryConstructor.QUERY_TYPE)) { baseQuery = ((CustomQueryConstructor)queryConstructor).doConstructCustomQuery(jsonValue, qparser); } else { baseQuery = queryConstructor.doConstructQuery(jsonValue); } JSONObject jsonRelevance = null; if(jsonValue.has(RELEVANCE)) { jsonRelevance = jsonValue.optJSONObject(RELEVANCE); if(jsonRelevance == null) throw new JSONException("relevance part of the query json can not be parsed."); } if(jsonRelevance == null) { return baseQuery; } else { // the olde code path, now turned off; // return new RelevanceQuery(baseQuery, jsonRelevance); ScoreAugmentFunction func = RelevanceFunctionBuilder.build(jsonRelevance); JSONObject valuesJson = jsonRelevance.optJSONObject(RelevanceJSONConstants.KW_VALUES); if(func == null) throw new JSONException("Can not create the score function;"); return new ScoreAugmentQuery(baseQuery, func, valuesJson); } } abstract public Query doConstructQuery(JSONObject jsonQuery) throws JSONException; }