Пример #1
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);
  }