/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. *   * Licensed 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.dashbuilder.dataprovider.backend.elasticsearch.rest.impl; import org.dashbuilder.dataprovider.backend.elasticsearch.rest.model.Query; import org.elasticsearch.index.query.*; import java.util.Collection; /** * Helper class for the ELS native client that provides the different <code>QueryBuilder</code>'s given a query. * * @since 0.5.0 */ public class NativeClientQueryBuilder { public NativeClientQueryBuilder( ) { } public QueryBuilder build( Query query ) { return translate( query ); } private QueryBuilder translate( Query query ) { if ( query == null ) { return null; } Query.Type type = query.getType(); switch (type) { case BOOL: return translateBool(query); case MATCH: return translateMatch(query); case MATCH_ALL: return translateMatchAll(query); case WILDCARD: return translateWildcard(query); case QUERY_STRING: return translateQueryString(query); case FILTERED: return translateFiltered(query); case AND: return translateAnd(query); case OR: return translateOr(query); case NOT: return translateNot(query); case EXISTS: return translateExists(query); case TERM: return translateTerm(query); case TERMS: return translateTerms(query); case RANGE: return translateRange(query); } return null; } private ExistsQueryBuilder translateExists(Query query) { if (query == null) return null; String field = query.getField(); return new ExistsQueryBuilder( field ); } private TermQueryBuilder translateTerm(Query query) { if (query == null) return null; String field = query.getField(); Object value = query.getParam(Query.Parameter.VALUE.name()); return new TermQueryBuilder( field, value ); } private TermsQueryBuilder translateTerms(Query query) { if (query == null) return null; String field = query.getField(); Collection<String> terms = (Collection<String>) query.getParam(Query.Parameter.VALUE.name()); return new TermsQueryBuilder( field, terms); } private RangeQueryBuilder translateRange(Query query) { if (query == null) return null; String field = query.getField(); RangeQueryBuilder builder = new RangeQueryBuilder( field ); Object lt = query.getParam(Query.Parameter.LT.name()); if ( null != lt ) { builder.lt( lt ); } Object lte = query.getParam(Query.Parameter.LTE.name()); if ( null != lte ) { builder.lte( lte ); } Object gt = query.getParam(Query.Parameter.GT.name()); if ( null != gt ) { builder.gt( gt ); } Object gte = query.getParam(Query.Parameter.GTE.name()); if ( null != gte ) { builder.gte( gte ); } return builder; } private BoolQueryBuilder translateAnd(Query query) { return translateLogical( query, 1 ); } private BoolQueryBuilder translateOr(Query query) { return translateLogical( query, 2 ); } private BoolQueryBuilder translateNot(Query query) { return translateBooleanQueries( new BoolQueryBuilder(), 3, query.getParam(Query.Parameter.FILTER.name()) ); } private BoolQueryBuilder translateLogical( Query query, int op ) { return translateBooleanQueries( new BoolQueryBuilder(), op, query.getParam(Query.Parameter.FILTERS.name()) ); } @SuppressWarnings("unchecked") private BoolQueryBuilder translateBooleanQueries( BoolQueryBuilder builder, int op, Object queryArguments ) { if ( op == 2 ) { builder.minimumNumberShouldMatch( 1 ); } if ( null != queryArguments && queryArguments instanceof Collection ) { Collection<Query> queries = (Collection<Query>) queryArguments; for ( Query q : queries ) { QueryBuilder queryBuilder = translate( q ); applyLogicalOperator( builder, op, queryBuilder ); } } else if ( null != queryArguments && queryArguments instanceof Query ) { QueryBuilder queryBuilder = translate( (Query) queryArguments ); applyLogicalOperator( builder, op, queryBuilder ); } else if ( null != queryArguments && queryArguments instanceof QueryBuilder ) { applyLogicalOperator( builder, op, (QueryBuilder) queryArguments ); } return builder; } private void applyLogicalOperator( BoolQueryBuilder builder, int op, QueryBuilder argument ) { if ( op == 1 ) { builder.must( argument ); } else if ( op == 2 ) { builder.should( argument ); } else if ( op == 3 ) { builder.mustNot( argument ); } } private BoolQueryBuilder translateBool(Query query) { if (query == null) return null; BoolQueryBuilder builder = new BoolQueryBuilder(); // Must clauses. translateBooleanQueries( builder, 1, query.getParam(Query.Parameter.MUST.name()) ); // Should clauses. translateBooleanQueries( builder, 2, query.getParam(Query.Parameter.SHOULD.name()) ); // Must Not clauses. translateBooleanQueries( builder, 3, query.getParam(Query.Parameter.MUST_NOT.name()) ); return builder; } private BoolQueryBuilder translateFiltered(Query query) { if (query == null) return null; Query _query = (Query) query.getParam(Query.Parameter.QUERY.name()); Query filter = (Query) query.getParam(Query.Parameter.FILTER.name()); BoolQueryBuilder builder = new BoolQueryBuilder(); QueryBuilder queryBuilder = translate( _query ); if ( null != queryBuilder ) { builder.must( queryBuilder ); } QueryBuilder filterBuilder = translate( filter ); if ( null != filter ) { builder.filter( filterBuilder ); } return builder; } private MatchQueryBuilder translateMatch( Query query ) { if (query == null) return null; String field = query.getField(); Object value = query.getParam(Query.Parameter.VALUE.name()); String operator = (String) query.getParam(Query.Parameter.OPERATOR.name()); MatchQueryBuilder builder = new MatchQueryBuilder( field, value ); if ( null != operator ) { builder.operator( getMatchOperator( operator ) ); builder.minimumShouldMatch( "1" ); } return builder; } private MatchQueryBuilder.Operator getMatchOperator( String op ) { if ( "OR".equalsIgnoreCase( op) ) { return MatchQueryBuilder.Operator.OR; } return MatchQueryBuilder.Operator.AND; } private WildcardQueryBuilder translateWildcard( Query query ) { if (query == null) return null; String field = query.getField(); Object value = query.getParam( Query.Parameter.VALUE.name() ); return new WildcardQueryBuilder( field, (String) value ); } private QueryStringQueryBuilder translateQueryString( Query query ) { if (query == null) return null; Object pattern = query.getParam(Query.Parameter.QUERY.name()); Object defField = query.getParam(Query.Parameter.DEFAULT_FIELD.name()); Object defOp = query.getParam(Query.Parameter.DEFAULT_OPERATOR.name()); Object lowerCase = query.getParam(Query.Parameter.LOWERCASE_EXPANDED_TERMS.name()); return new QueryStringQueryBuilder( pattern.toString() ) .defaultField( defField.toString() ) .defaultOperator( getQueryOperator( defOp.toString() ) ) .lowercaseExpandedTerms( Boolean.valueOf( lowerCase.toString() ) ); } private QueryStringQueryBuilder.Operator getQueryOperator( String op ) { if ( "OR".equalsIgnoreCase( op ) ) { return QueryStringQueryBuilder.Operator.OR; } return QueryStringQueryBuilder.Operator.AND; } private MatchAllQueryBuilder translateMatchAll( Query query ) { if (query == null) return null; return new MatchAllQueryBuilder(); } }