public SignificantTermsAggregatorFactory(
      String name,
      ValuesSourceConfig valueSourceConfig,
      TermsAggregator.BucketCountThresholds bucketCountThresholds,
      IncludeExclude includeExclude,
      String executionHint,
      Query filter,
      SignificanceHeuristic significanceHeuristic) {

    super(name, SignificantStringTerms.TYPE.name(), valueSourceConfig);
    this.bucketCountThresholds = bucketCountThresholds;
    this.includeExclude = includeExclude;
    this.executionHint = executionHint;
    this.significanceHeuristic = significanceHeuristic;
    if (!valueSourceConfig.unmapped()) {
      this.indexedFieldName = config.fieldContext().field();
      fieldType = SearchContext.current().smartNameFieldType(indexedFieldName);
    }
    this.filter = filter;
  }
예제 #2
0
  @Override
  public AggregatorFactory parse(
      String aggregationName, XContentParser parser, SearchContext context) throws IOException {

    ValuesSourceConfig<NumericValuesSource> config =
        new ValuesSourceConfig<NumericValuesSource>(NumericValuesSource.class);

    String field = null;
    List<RangeAggregator.Range> ranges = null;
    String script = null;
    String scriptLang = null;
    Map<String, Object> scriptParams = null;
    boolean keyed = false;
    boolean assumeSorted = false;

    XContentParser.Token token;
    String currentFieldName = null;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.VALUE_STRING) {
        if ("field".equals(currentFieldName)) {
          field = parser.text();
        } else if ("script".equals(currentFieldName)) {
          script = parser.text();
        } else if ("lang".equals(currentFieldName)) {
          scriptLang = parser.text();
        } else {
          throw new SearchParseException(
              context,
              "Unknown key for a "
                  + token
                  + " in ["
                  + aggregationName
                  + "]: ["
                  + currentFieldName
                  + "].");
        }
      } else if (token == XContentParser.Token.START_ARRAY) {
        if ("ranges".equals(currentFieldName)) {
          ranges = new ArrayList<RangeAggregator.Range>();
          while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
            double from = Double.NEGATIVE_INFINITY;
            String fromAsStr = null;
            double to = Double.POSITIVE_INFINITY;
            String toAsStr = null;
            String key = null;
            String toOrFromOrKey = null;
            while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
              if (token == XContentParser.Token.FIELD_NAME) {
                toOrFromOrKey = parser.currentName();
              } else if (token == XContentParser.Token.VALUE_NUMBER) {
                if ("from".equals(toOrFromOrKey)) {
                  from = parser.doubleValue();
                } else if ("to".equals(toOrFromOrKey)) {
                  to = parser.doubleValue();
                }
              } else if (token == XContentParser.Token.VALUE_STRING) {
                if ("from".equals(toOrFromOrKey)) {
                  fromAsStr = parser.text();
                } else if ("to".equals(toOrFromOrKey)) {
                  toAsStr = parser.text();
                } else if ("key".equals(toOrFromOrKey)) {
                  key = parser.text();
                }
              }
            }
            ranges.add(new RangeAggregator.Range(key, from, fromAsStr, to, toAsStr));
          }
        } else {
          throw new SearchParseException(
              context,
              "Unknown key for a "
                  + token
                  + " in ["
                  + aggregationName
                  + "]: ["
                  + currentFieldName
                  + "].");
        }
      } else if (token == XContentParser.Token.START_OBJECT) {
        if ("params".equals(currentFieldName)) {
          scriptParams = parser.map();
        } else {
          throw new SearchParseException(
              context,
              "Unknown key for a "
                  + token
                  + " in ["
                  + aggregationName
                  + "]: ["
                  + currentFieldName
                  + "].");
        }
      } else if (token == XContentParser.Token.VALUE_BOOLEAN) {
        if ("keyed".equals(currentFieldName)) {
          keyed = parser.booleanValue();
        } else if ("script_values_sorted".equals(currentFieldName)) {
          assumeSorted = parser.booleanValue();
        } else {
          throw new SearchParseException(
              context,
              "Unknown key for a "
                  + token
                  + " in ["
                  + aggregationName
                  + "]: ["
                  + currentFieldName
                  + "].");
        }
      } else {
        throw new SearchParseException(
            context, "Unexpected token " + token + " in [" + aggregationName + "].");
      }
    }

    if (ranges == null) {
      throw new SearchParseException(
          context, "Missing [ranges] in ranges aggregator [" + aggregationName + "]");
    }

    if (script != null) {
      config.script(
          context.scriptService().search(context.lookup(), scriptLang, script, scriptParams));
    }

    if (!assumeSorted) {
      // we need values to be sorted and unique for efficiency
      config.ensureSorted(true);
    }

    if (field == null) {
      return new RangeAggregator.Factory(
          aggregationName, config, InternalRange.FACTORY, ranges, keyed);
    }

    FieldMapper<?> mapper = context.smartNameFieldMapper(field);
    if (mapper == null) {
      config.unmapped(true);
      return new RangeAggregator.Factory(
          aggregationName, config, InternalRange.FACTORY, ranges, keyed);
    }

    IndexFieldData<?> indexFieldData = context.fieldData().getForField(mapper);
    config.fieldContext(new FieldContext(field, indexFieldData));
    return new RangeAggregator.Factory(
        aggregationName, config, InternalRange.FACTORY, ranges, keyed);
  }
예제 #3
0
  @Override
  public AggregatorFactory parse(
      String aggregationName, XContentParser parser, SearchContext context) throws IOException {
    String childType = null;

    XContentParser.Token token;
    String currentFieldName = null;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.VALUE_STRING) {
        if ("type".equals(currentFieldName)) {
          childType = parser.text();
        } else {
          throw new SearchParseException(
              context,
              "Unknown key for a "
                  + token
                  + " in ["
                  + aggregationName
                  + "]: ["
                  + currentFieldName
                  + "].");
        }
      } else {
        throw new SearchParseException(
            context, "Unexpected token " + token + " in [" + aggregationName + "].");
      }
    }

    if (childType == null) {
      throw new SearchParseException(
          context, "Missing [child_type] field for children aggregation [" + aggregationName + "]");
    }

    DocumentMapper childDocMapper = context.mapperService().documentMapper(childType);
    if (childDocMapper == null) {
      throw new SearchParseException(
          context, "[children] No mapping for for type [" + childType + "]");
    }
    ParentFieldMapper parentFieldMapper = childDocMapper.parentFieldMapper();
    if (!parentFieldMapper.active()) {
      throw new SearchParseException(context, "[children] _parent field not configured");
    }

    String parentType = parentFieldMapper.type();
    DocumentMapper parentDocMapper = context.mapperService().documentMapper(parentType);
    if (parentDocMapper == null) {
      throw new SearchParseException(
          context,
          "[children]  Type ["
              + childType
              + "] points to a non existent parent type ["
              + parentType
              + "]");
    }

    Filter parentFilter = context.filterCache().cache(parentDocMapper.typeFilter());
    Filter childFilter = context.filterCache().cache(childDocMapper.typeFilter());

    ParentChildIndexFieldData parentChildIndexFieldData =
        context.fieldData().getForField(parentFieldMapper);
    ValuesSourceConfig<ValuesSource.Bytes.WithOrdinals.ParentChild> config =
        new ValuesSourceConfig<>(ValuesSource.Bytes.WithOrdinals.ParentChild.class);
    config.fieldContext(
        new FieldContext(
            parentFieldMapper.names().indexName(), parentChildIndexFieldData, parentFieldMapper));
    return new ParentToChildrenAggregator.Factory(
        aggregationName, config, parentType, parentFilter, childFilter);
  }
예제 #4
0
  @Override
  public AggregatorFactory parse(
      String aggregationName, XContentParser parser, SearchContext context) throws IOException {

    String field = null;
    String script = null;
    String scriptLang = null;
    Map<String, Object> scriptParams = null;
    Terms.ValueType valueType = null;
    int requiredSize = 10;
    String orderKey = "_count";
    boolean orderAsc = false;
    String format = null;
    boolean assumeUnique = false;

    XContentParser.Token token;
    String currentFieldName = null;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.VALUE_STRING) {
        if ("field".equals(currentFieldName)) {
          field = parser.text();
        } else if ("script".equals(currentFieldName)) {
          script = parser.text();
        } else if ("script_lang".equals(currentFieldName)
            || "scriptLang".equals(currentFieldName)) {
          scriptLang = parser.text();
        } else if ("value_type".equals(currentFieldName) || "valueType".equals(currentFieldName)) {
          valueType = Terms.ValueType.resolveType(parser.text());
        } else if ("format".equals(currentFieldName)) {
          format = parser.text();
        }
      } else if (token == XContentParser.Token.VALUE_BOOLEAN) {
        if ("script_values_unique".equals(currentFieldName)) {
          assumeUnique = parser.booleanValue();
        }
      } else if (token == XContentParser.Token.VALUE_NUMBER) {
        if ("size".equals(currentFieldName)) {
          requiredSize = parser.intValue();
        }
      } else if (token == XContentParser.Token.START_OBJECT) {
        if ("params".equals(currentFieldName)) {
          scriptParams = parser.map();
        } else if ("order".equals(currentFieldName)) {
          while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
            if (token == XContentParser.Token.FIELD_NAME) {
              orderKey = parser.currentName();
            } else if (token == XContentParser.Token.VALUE_STRING) {
              String dir = parser.text();
              orderAsc = "asc".equalsIgnoreCase(dir);
              // TODO: do we want to throw a parse error if the alternative is not "desc"???
            }
          }
        }
      }
    }

    InternalOrder order = resolveOrder(orderKey, orderAsc);
    SearchScript searchScript = null;
    if (script != null) {
      searchScript =
          context.scriptService().search(context.lookup(), scriptLang, script, scriptParams);
    }

    if (field == null) {

      Class<? extends ValuesSource> valueSourceType =
          script == null
              ? ValuesSource.class
              : // unknown, will inherit whatever is in the context
              valueType != null
                  ? valueType.scriptValueType.getValuesSourceType()
                  : // the user explicitly defined a value type
                  BytesValuesSource.class; // defaulting to bytes

      ValuesSourceConfig<?> config = new ValuesSourceConfig(valueSourceType);
      if (valueType != null) {
        config.scriptValueType(valueType.scriptValueType);
      }
      config.script(searchScript);
      if (!assumeUnique) {
        config.ensureUnique(true);
      }
      return new TermsAggregatorFactory(aggregationName, config, order, requiredSize);
    }

    FieldMapper<?> mapper = context.smartNameFieldMapper(field);
    if (mapper == null) {
      ValuesSourceConfig<?> config =
          new ValuesSourceConfig<BytesValuesSource>(BytesValuesSource.class);
      config.unmapped(true);
      return new TermsAggregatorFactory(aggregationName, config, order, requiredSize);
    }
    IndexFieldData<?> indexFieldData = context.fieldData().getForField(mapper);

    ValuesSourceConfig<?> config;

    if (mapper instanceof DateFieldMapper) {
      DateFieldMapper dateMapper = (DateFieldMapper) mapper;
      ValueFormatter formatter =
          format == null
              ? new ValueFormatter.DateTime(dateMapper.dateTimeFormatter())
              : new ValueFormatter.DateTime(format);
      config =
          new ValuesSourceConfig<NumericValuesSource>(NumericValuesSource.class)
              .formatter(formatter)
              .parser(new ValueParser.DateMath(dateMapper.dateMathParser()));

    } else if (mapper instanceof IpFieldMapper) {
      config =
          new ValuesSourceConfig<NumericValuesSource>(NumericValuesSource.class)
              .formatter(ValueFormatter.IPv4)
              .parser(ValueParser.IPv4);

    } else if (indexFieldData instanceof IndexNumericFieldData) {
      config = new ValuesSourceConfig<NumericValuesSource>(NumericValuesSource.class);
      if (format != null) {
        config.formatter(new ValueFormatter.Number.Pattern(format));
      }

    } else {
      config = new ValuesSourceConfig<BytesValuesSource>(BytesValuesSource.class);
      // TODO: it will make sense to set false instead here if the aggregator factory uses
      // ordinals instead of hash tables
      config.needsHashes(true);
    }

    config.script(searchScript);

    config.fieldContext(new FieldContext(field, indexFieldData));

    // We need values to be unique to be able to run terms aggs efficiently
    if (!assumeUnique) {
      config.ensureUnique(true);
    }

    return new TermsAggregatorFactory(aggregationName, config, order, requiredSize);
  }