protected Query between(Operation<?> operation, QueryMetadata metadata) { verifyArguments(operation); Path<?> path = getPath(operation.getArg(0)); // TODO Phrase not properly supported return range( path, toField(path), operation.getArg(1), operation.getArg(2), true, true, metadata); }
private Query toQuery(Operation<?> operation, QueryMetadata metadata) { Operator op = operation.getOperator(); if (op == Ops.OR) { return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); } else if (op == Ops.AND) { return toTwoHandSidedQuery(operation, Occur.MUST, metadata); } else if (op == Ops.NOT) { BooleanQuery bq = new BooleanQuery(); bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); return bq; } else if (op == Ops.LIKE) { return like(operation, metadata); } else if (op == Ops.LIKE_IC) { throw new IgnoreCaseUnsupportedException(); } else if (op == Ops.EQ) { return eq(operation, metadata, false); } else if (op == Ops.EQ_IGNORE_CASE) { throw new IgnoreCaseUnsupportedException(); } else if (op == Ops.NE) { return ne(operation, metadata, false); } else if (op == Ops.STARTS_WITH) { return startsWith(metadata, operation, false); } else if (op == Ops.STARTS_WITH_IC) { throw new IgnoreCaseUnsupportedException(); } else if (op == Ops.ENDS_WITH) { return endsWith(operation, metadata, false); } else if (op == Ops.ENDS_WITH_IC) { throw new IgnoreCaseUnsupportedException(); } else if (op == Ops.STRING_CONTAINS) { return stringContains(operation, metadata, false); } else if (op == Ops.STRING_CONTAINS_IC) { throw new IgnoreCaseUnsupportedException(); } else if (op == Ops.BETWEEN) { return between(operation, metadata); } else if (op == Ops.IN) { return in(operation, metadata, false); } else if (op == Ops.NOT_IN) { return notIn(operation, metadata, false); } else if (op == Ops.LT) { return lt(operation, metadata); } else if (op == Ops.GT) { return gt(operation, metadata); } else if (op == Ops.LOE) { return le(operation, metadata); } else if (op == Ops.GOE) { return ge(operation, metadata); } else if (op == LuceneOps.LUCENE_QUERY) { @SuppressWarnings("unchecked") // This is the expected type Query rv = ((Constant<Query>) operation.getArg(0)).getConstant(); return rv; } throw new UnsupportedOperationException("Illegal operation " + operation); }
private Path<?> getPath(Expression<?> leftHandSide) { if (leftHandSide instanceof Path<?>) { return (Path<?>) leftHandSide; } else if (leftHandSide instanceof Operation<?>) { Operation<?> operation = (Operation<?>) leftHandSide; if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) { return (Path<?>) operation.getArg(0); } } throw new IllegalArgumentException("Unable to transform " + leftHandSide + " to path"); }
protected Query eq(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { verifyArguments(operation); Path<?> path = getPath(operation.getArg(0)); String field = toField(path); if (Number.class.isAssignableFrom(operation.getArg(1).getType())) { @SuppressWarnings("unchecked") // guarded by previous check Constant<? extends Number> rightArg = (Constant<? extends Number>) operation.getArg(1); return new TermQuery(new Term(field, convertNumber(rightArg.getConstant()))); } return eq(field, convert(path, operation.getArg(1), metadata), ignoreCase); }
protected Query like(Operation<?> operation, QueryMetadata metadata) { verifyArguments(operation); Path<?> path = getPath(operation.getArg(0)); String field = toField(path); String[] terms = convert(path, operation.getArg(1)); if (terms.length > 1) { BooleanQuery bq = new BooleanQuery(); for (String s : terms) { bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); } return bq; } return new WildcardQuery(new Term(field, terms[0])); }
protected Query endsWith(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { verifyArguments(operation); Path<?> path = getPath(operation.getArg(0)); String field = toField(path); String[] terms = convertEscaped(path, operation.getArg(1), metadata); if (terms.length > 1) { BooleanQuery bq = new BooleanQuery(); for (int i = 0; i < terms.length; ++i) { String s = i == terms.length - 1 ? "*" + terms[i] : "*" + terms[i] + "*"; bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); } return bq; } return new WildcardQuery(new Term(field, "*" + terms[0])); }
private Query toTwoHandSidedQuery(Operation<?> operation, Occur occur, QueryMetadata metadata) { Query lhs = toQuery(operation.getArg(0), metadata); Query rhs = toQuery(operation.getArg(1), metadata); BooleanQuery bq = new BooleanQuery(); bq.add(createBooleanClause(lhs, occur)); bq.add(createBooleanClause(rhs, occur)); return bq; }
protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { Path<?> path = getPath(operation.getArg(0)); String field = toField(path); @SuppressWarnings("unchecked") // This is the second argument type Constant<Collection<?>> collConstant = (Constant<Collection<?>>) operation.getArg(1); Collection<?> values = collConstant.getConstant(); BooleanQuery bq = new BooleanQuery(); if (Number.class.isAssignableFrom(path.getType())) { for (Object value : values) { TermQuery eq = new TermQuery(new Term(field, convertNumber((Number) value))); bq.add(eq, Occur.SHOULD); } } else { for (Object value : values) { String[] str = convert(path, value); bq.add(eq(field, str, ignoreCase), Occur.SHOULD); } } return bq; }
private void verifyArguments(Operation<?> operation) { List<Expression<?>> arguments = operation.getArgs(); for (int i = 1; i < arguments.size(); ++i) { if (!(arguments.get(i) instanceof Constant<?>) && !(arguments.get(i) instanceof ParamExpression<?>) && !(arguments.get(i) instanceof PhraseElement) && !(arguments.get(i) instanceof TermElement)) { throw new IllegalArgumentException( "operand was of unsupported type " + arguments.get(i).getClass().getName()); } } }
/** * template method * * @param leftHandSide left hand side * @param rightHandSide right hand side * @return results */ protected String[] convert( Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { if (rightHandSide instanceof Operation) { Operation<?> operation = (Operation<?>) rightHandSide; if (operation.getOperator() == LuceneOps.PHRASE) { return Iterables.toArray(WS_SPLITTER.split(operation.getArg(0).toString()), String.class); } else if (operation.getOperator() == LuceneOps.TERM) { return new String[] {operation.getArg(0).toString()}; } else { throw new IllegalArgumentException(rightHandSide.toString()); } } else if (rightHandSide instanceof ParamExpression<?>) { Object value = metadata.getParams().get(rightHandSide); if (value == null) { throw new ParamNotSetException((ParamExpression<?>) rightHandSide); } return convert(leftHandSide, value); } else if (rightHandSide instanceof Constant<?>) { return convert(leftHandSide, ((Constant<?>) rightHandSide).getConstant()); } else { throw new IllegalArgumentException(rightHandSide.toString()); } }
protected Query ge(Operation<?> operation, QueryMetadata metadata) { verifyArguments(operation); Path<?> path = getPath(operation.getArg(0)); return range(path, toField(path), operation.getArg(1), null, true, true, metadata); }