001/*
002 * (C) Copyright 2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Gethin James
018 */
019package org.nuxeo.elasticsearch.aggregate;
020
021import java.util.function.Consumer;
022
023import org.elasticsearch.index.query.QueryBuilder;
024import org.elasticsearch.index.query.QueryBuilders;
025import org.elasticsearch.search.aggregations.Aggregation;
026import org.elasticsearch.search.aggregations.AggregationBuilder;
027import org.nuxeo.ecm.platform.query.api.AggregateDefinition;
028import org.nuxeo.ecm.platform.query.api.Bucket;
029import org.nuxeo.ecm.platform.query.core.AggregateDescriptor;
030
031/**
032 * This class is intended for internal/advanced use. It supports any ElasticSearch aggregate builder as a constructor
033 * parameter. However, it doesn't support Nuxeo page providers or the aggregation factory. The other aggregate classes
034 * are the preferred approach.
035 *
036 * @since 10.3
037 */
038public class NativeEsAggregate extends AggregateEsBase<Aggregation, Bucket> {
039
040    protected final AggregationBuilder nativeAggregation;
041
042    protected final Consumer<Aggregation> parser;
043
044    public NativeEsAggregate(AggregateDefinition definition, AggregationBuilder nativeAggregation,
045            Consumer<Aggregation> parser) {
046        super(definition, null);
047        this.nativeAggregation = nativeAggregation;
048        this.parser = parser;
049    }
050
051    /**
052     * Construct the aggregate using an ElasticSearch aggregate builder and a parser that will consume the response.
053     */
054    public NativeEsAggregate(AggregationBuilder nativeAggregation, Consumer<Aggregation> parser) {
055        this(makeDefinition(nativeAggregation), nativeAggregation, parser);
056    }
057
058    /**
059     * For backwards compatibility make an AggregateDefinition.
060     */
061    protected static AggregateDefinition makeDefinition(AggregationBuilder nativeAggregation) {
062        AggregateDescriptor descriptor = new AggregateDescriptor();
063        descriptor.setId(nativeAggregation.getName());
064        return descriptor;
065    }
066
067    @Override
068    public AggregationBuilder getEsAggregate() {
069        return nativeAggregation;
070    }
071
072    @Override
073    public QueryBuilder getEsFilter() {
074        if (getSelection().isEmpty()) {
075            return null;
076        }
077        return QueryBuilders.termsQuery(getField(), getSelection());
078    }
079
080    @Override
081    public void parseAggregation(Aggregation aggregation) {
082        parser.accept(aggregation);
083    }
084
085    @Override
086    public String toString() {
087        return nativeAggregation.toString();
088    }
089}