@Override protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException { if (node instanceof AqpWhiteSpacedQueryNode) { QueryConfigHandler config = getQueryConfigHandler(); if (!config.has( AqpAdsabsQueryConfigHandler.ConfigurationKeys.FUNCTION_QUERY_BUILDER_CONFIG)) { throw new QueryNodeException( new MessageImpl("Invalid configuration", "Missing FunctionQueryBuilder provider")); } String funcName = getFuncName(); String subQuery = ((FieldQueryNode) node).getTextAsString(); String field = ((FieldQueryNode) node).getFieldAsString(); if (field.equals( config.get(AqpAdsabsQueryConfigHandler.ConfigurationKeys.UNFIELDED_SEARCH_FIELD))) { field = null; } if (field != null) { subQuery = field + ":" + subQuery; } if (node.getParent() instanceof SlopQueryNode) { subQuery = "(" + subQuery + ")"; subQuery = subQuery + "~" + ((SlopQueryNode) node.getParent()).getValue(); if (node.getParent().getParent() instanceof BoostQueryNode) { subQuery = subQuery + "^" + ((BoostQueryNode) node.getParent().getParent()).getValue(); } } else if (node.getParent() instanceof BoostQueryNode) { subQuery = "(" + subQuery + ")"; subQuery = subQuery + "^" + ((BoostQueryNode) node.getParent()).getValue(); } node.setTag("subQuery", subQuery); AqpFunctionQueryBuilder builder = config .get(AqpAdsabsQueryConfigHandler.ConfigurationKeys.FUNCTION_QUERY_BUILDER_CONFIG) .getBuilder(funcName, (QueryNode) node, config); if (builder == null) { throw new QueryNodeException( new MessageImpl( QueryParserMessages.INVALID_SYNTAX, "Unknown function: \"" + funcName + "\"")); } List<OriginalInput> fValues = new ArrayList<OriginalInput>(); fValues.add( new OriginalInput( subQuery, ((AqpWhiteSpacedQueryNode) node).getBegin(), ((AqpWhiteSpacedQueryNode) node).getEnd())); return new AqpFunctionQueryNode(funcName, builder, fValues); } return node; }
public static String getDefaultDatatype(QueryConfigHandler config) { if (config.has(KeywordConfigurationKeys.DEFAULT_DATATYPE)) { return config.get(KeywordConfigurationKeys.DEFAULT_DATATYPE); } else { throw new IllegalArgumentException( "KeywordConfigurationKeys.DEFAULT_DATATYPE should be set on the ExtendedKeywordQueryConfigHandler"); } }
@Override protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException { final QueryConfigHandler conf = this.getQueryConfigHandler(); // If the current node is a datatype query node, validate the datatype and assign it to its // child if (node instanceof DatatypeQueryNode) { final Map<String, Analyzer> dtAnalyzers = conf.get(KeywordConfigurationKeys.DATATYPES_ANALYZERS); final DatatypeQueryNode dt = (DatatypeQueryNode) node; String datatype = dt.getDatatype(); // check if the datatype is correctly registered if (dtAnalyzers == null) { throw new IllegalArgumentException( "KeywordConfigurationKeys.DATAYPES_ANALYZERS " + "should be set on the ExtendedKeywordQueryConfigHandler"); } if (!dtAnalyzers.containsKey(datatype)) { throw new IllegalArgumentException("Unknown datatype: [" + datatype + "]"); } if (dtAnalyzers.get(datatype) == null) { throw new IllegalArgumentException( "Analyzer of datatype [" + datatype + "] cannot be null."); } // transfer the datatype to its child dt.getChild().setTag(DatatypeQueryNode.DATATYPE_TAGID, datatype); } // If the current node is a twig query node, assign the json:field datatype to the root, and // assign the default // or the tagged datatype to the child else if (node instanceof TwigQueryNode) { final TwigQueryNode twig = (TwigQueryNode) node; if (twig.getTag(DatatypeQueryNode.DATATYPE_TAGID) == null) { twig.getChild().setTag(DatatypeQueryNode.DATATYPE_TAGID, this.getDefaultDatatype(conf)); } else { twig.getChild().setTag(DatatypeQueryNode.DATATYPE_TAGID, this.getDatatype(conf, node)); } twig.getRoot().setTag(DatatypeQueryNode.DATATYPE_TAGID, JSONDatatype.JSON_FIELD); } // in any other cases, if the node is not a leaf node, transfer the datatype to its children else if (!node.isLeaf()) { for (final QueryNode child : node.getChildren()) { child.setTag(DatatypeQueryNode.DATATYPE_TAGID, this.getDatatype(conf, node)); } } return node; }
public QueryNode createQNode(AqpANTLRNode node) throws QueryNodeException { String field = getDefaultFieldName(); AqpANTLRNode subChild = (AqpANTLRNode) node.getChildren().get(0); String input = subChild.getTokenInput(); if (input.contains("*?") || input.contains("?*")) { throw new QueryNodeException( new MessageImpl( QueryParserMessages.INVALID_SYNTAX, "It is not allowed to put '*' next to '?'" + input)); } // special exception, we don't want query '*' to be passed // further on, it would be grabbed by edismax; and also // if it was a fielded query 'field:*', we make of it a prefix query QueryConfigHandler config = getQueryConfigHandler(); if (input.equals("*")) { if (node.getParent().getChildren().size() == 1) { // no field return new MatchAllDocsQueryNode(); } QueryNode fieldNode = node.getParent().getChildren().get(0); String unfieldedName = config.get(AqpAdsabsQueryConfigHandler.ConfigurationKeys.UNFIELDED_SEARCH_FIELD); if (fieldNode instanceof AqpANTLRNode) { if (((AqpANTLRNode) fieldNode).getTokenInput() != null && !((AqpANTLRNode) fieldNode).getTokenInput().equals(unfieldedName)) { return new PrefixWildcardQueryNode( ((AqpANTLRNode) fieldNode).getTokenInput(), "*", subChild.getTokenStart(), subChild.getTokenEnd()); } } else { return new MatchAllDocsQueryNode(); } } return new WildcardQueryNode( field, EscapeQuerySyntaxImpl.discardEscapeChar(input), subChild.getTokenStart(), subChild.getTokenEnd()); }
@Override public void buildFieldConfig(FieldConfig fieldConfig) { Map<String, NumericConfig> numericConfigMap = config.get(ConfigurationKeys.NUMERIC_CONFIG_MAP); if (numericConfigMap != null) { NumericConfig numericConfig = numericConfigMap.get(fieldConfig.getField()); if (numericConfig != null) { fieldConfig.set(ConfigurationKeys.NUMERIC_CONFIG, numericConfig); } } }
@Override public Query build(final QueryNode queryNode) throws QueryNodeException { if (conf.has(ConciseKeywordQueryConfigHandler.ConciseKeywordConfigurationKeys.ATTRIBUTE)) { final String attribute = conf.get(ConciseKeywordQueryConfigHandler.ConciseKeywordConfigurationKeys.ATTRIBUTE); final String field = conf.get(ConciseKeywordQueryConfigHandler.ConciseKeywordConfigurationKeys.FIELD); // create the node term query NodeTermQuery ntq = new NodeTermQuery( new Term(field, ConciseNodeBuilderUtil.prepend(builder, attribute, ""))); // assign the datatype. We must always have a datatype assigned. String datatype = DatatypeProcessor.getDefaultDatatype(this.conf); ntq.setDatatype(datatype); return ntq; } else { return new BooleanQuery(); } }
@Override protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException { if (node instanceof TermRangeQueryNode) { QueryConfigHandler config = getQueryConfigHandler(); if (config != null) { TermRangeQueryNode termRangeNode = (TermRangeQueryNode) node; FieldConfig fieldConfig = config.getFieldConfig(StringUtils.toString(termRangeNode.getField())); if (fieldConfig != null) { NumericConfig numericConfig = fieldConfig.get(ConfigurationKeys.NUMERIC_CONFIG); if (numericConfig != null) { FieldQueryNode lower = termRangeNode.getLowerBound(); FieldQueryNode upper = termRangeNode.getUpperBound(); String lowerText = lower.getTextAsString(); String upperText = upper.getTextAsString(); NumberFormat numberFormat = numericConfig.getNumberFormat(); Number lowerNumber = null, upperNumber = null; if (lowerText.length() > 0) { try { lowerNumber = numberFormat.parse(lowerText); } catch (ParseException e) { throw new QueryNodeParseException( new MessageImpl( QueryParserMessages.COULD_NOT_PARSE_NUMBER, lower.getTextAsString(), numberFormat.getClass().getCanonicalName()), e); } } if (upperText.length() > 0) { try { upperNumber = numberFormat.parse(upperText); } catch (ParseException e) { throw new QueryNodeParseException( new MessageImpl( QueryParserMessages.COULD_NOT_PARSE_NUMBER, upper.getTextAsString(), numberFormat.getClass().getCanonicalName()), e); } } switch (numericConfig.getType()) { case LONG: if (upperNumber != null) upperNumber = upperNumber.longValue(); if (lowerNumber != null) lowerNumber = lowerNumber.longValue(); break; case INT: if (upperNumber != null) upperNumber = upperNumber.intValue(); if (lowerNumber != null) lowerNumber = lowerNumber.intValue(); break; case DOUBLE: if (upperNumber != null) upperNumber = upperNumber.doubleValue(); if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue(); break; case FLOAT: if (upperNumber != null) upperNumber = upperNumber.floatValue(); if (lowerNumber != null) lowerNumber = lowerNumber.floatValue(); } NumericQueryNode lowerNode = new NumericQueryNode(termRangeNode.getField(), lowerNumber, numberFormat); NumericQueryNode upperNode = new NumericQueryNode(termRangeNode.getField(), upperNumber, numberFormat); boolean lowerInclusive = termRangeNode.isLowerInclusive(); boolean upperInclusive = termRangeNode.isUpperInclusive(); return new NumericRangeQueryNode( lowerNode, upperNode, lowerInclusive, upperInclusive, numericConfig); } } } } return node; }