@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;
  }
Example #2
0
 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");
   }
 }
Example #3
0
  @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;
  }