Ejemplo n.º 1
0
 /**
  * Constructs the AggregatorParsers out of all the given parsers
  *
  * @param parsers The available aggregator parsers (dynamically injected by the {@link
  *     org.elasticsearch.search.aggregations.AggregationModule}).
  */
 @Inject
 public AggregatorParsers(Set<Aggregator.Parser> parsers) {
   MapBuilder<String, Aggregator.Parser> builder = MapBuilder.newMapBuilder();
   for (Aggregator.Parser parser : parsers) {
     builder.put(parser.type(), parser);
   }
   this.parsers = builder.immutableMap();
 }
Ejemplo n.º 2
0
  private AggregatorFactories parseAggregators(
      XContentParser parser, SearchContext context, int level) throws IOException {
    Matcher validAggMatcher = VALID_AGG_NAME.matcher("");
    AggregatorFactories.Builder factories = new AggregatorFactories.Builder();

    XContentParser.Token token = null;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token != XContentParser.Token.FIELD_NAME) {
        throw new SearchParseException(
            context,
            "Unexpected token "
                + token
                + " in [aggs]: aggregations definitions must start with the name of the aggregation.");
      }
      final String aggregationName = parser.currentName();
      if (!validAggMatcher.reset(aggregationName).matches()) {
        throw new SearchParseException(
            context,
            "Invalid aggregation name ["
                + aggregationName
                + "]. Aggregation names must be alpha-numeric and can only contain '_' and '-'");
      }

      token = parser.nextToken();
      if (token != XContentParser.Token.START_OBJECT) {
        throw new SearchParseException(
            context,
            "Aggregation definition for ["
                + aggregationName
                + " starts with a ["
                + token
                + "], expected a ["
                + XContentParser.Token.START_OBJECT
                + "].");
      }

      AggregatorFactory factory = null;
      AggregatorFactories subFactories = null;

      while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
        if (token != XContentParser.Token.FIELD_NAME) {
          throw new SearchParseException(
              context,
              "Expected ["
                  + XContentParser.Token.FIELD_NAME
                  + "] under a ["
                  + XContentParser.Token.START_OBJECT
                  + "], but got a ["
                  + token
                  + "] in ["
                  + aggregationName
                  + "]");
        }
        final String fieldName = parser.currentName();

        token = parser.nextToken();
        if ("aggregations_binary".equals(fieldName)) {
          if (subFactories != null) {
            throw new SearchParseException(
                context, "Found two sub aggregation definitions under [" + aggregationName + "]");
          }
          XContentParser binaryParser = null;
          if (token == XContentParser.Token.VALUE_STRING
              || token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
            byte[] source = parser.binaryValue();
            binaryParser = XContentFactory.xContent(source).createParser(source);
          } else {
            throw new SearchParseException(
                context,
                "Expected ["
                    + XContentParser.Token.VALUE_STRING
                    + " or "
                    + XContentParser.Token.VALUE_EMBEDDED_OBJECT
                    + "] for ["
                    + fieldName
                    + "], but got a ["
                    + token
                    + "] in ["
                    + aggregationName
                    + "]");
          }
          XContentParser.Token binaryToken = binaryParser.nextToken();
          if (binaryToken != XContentParser.Token.START_OBJECT) {
            throw new SearchParseException(
                context,
                "Expected ["
                    + XContentParser.Token.START_OBJECT
                    + "] as first token when parsing ["
                    + fieldName
                    + "], but got a ["
                    + binaryToken
                    + "] in ["
                    + aggregationName
                    + "]");
          }
          subFactories = parseAggregators(binaryParser, context, level + 1);
        } else if (token == XContentParser.Token.START_OBJECT) {
          switch (fieldName) {
            case "aggregations":
            case "aggs":
              if (subFactories != null) {
                throw new SearchParseException(
                    context,
                    "Found two sub aggregation definitions under [" + aggregationName + "]");
              }
              subFactories = parseAggregators(parser, context, level + 1);
              break;
            default:
              if (factory != null) {
                throw new SearchParseException(
                    context,
                    "Found two aggregation type definitions in ["
                        + aggregationName
                        + "]: ["
                        + factory.type
                        + "] and ["
                        + fieldName
                        + "]");
              }
              Aggregator.Parser aggregatorParser = parser(fieldName);
              if (aggregatorParser == null) {
                throw new SearchParseException(
                    context,
                    "Could not find aggregator type ["
                        + fieldName
                        + "] in ["
                        + aggregationName
                        + "]");
              }
              factory = aggregatorParser.parse(aggregationName, parser, context);
          }
        } else {
          throw new SearchParseException(
              context,
              "Expected ["
                  + XContentParser.Token.START_OBJECT
                  + "] under ["
                  + fieldName
                  + "], but got a ["
                  + token
                  + "] in ["
                  + aggregationName
                  + "]");
        }
      }

      if (factory == null) {
        throw new SearchParseException(
            context, "Missing definition for aggregation [" + aggregationName + "]");
      }

      if (subFactories != null) {
        factory.subFactories(subFactories);
      }

      if (level == 0) {
        factory.validate();
      }

      factories.add(factory);
    }

    return factories.build();
  }