001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bdelbosc
016 */
017package org.nuxeo.elasticsearch.aggregate;
018
019import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_EXCLUDE_PROP;
020import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_INCLUDE_PROP;
021import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_MIN_DOC_COUNT_PROP;
022import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_ORDER_COUNT_ASC;
023import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_ORDER_COUNT_DESC;
024import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_ORDER_PROP;
025import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_ORDER_TERM_ASC;
026import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_ORDER_TERM_DESC;
027import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_SIZE_PROP;
028
029import java.util.ArrayList;
030import java.util.Collection;
031import java.util.List;
032import java.util.Map;
033
034import org.codehaus.jackson.annotate.JsonIgnore;
035import org.elasticsearch.index.query.FilterBuilders;
036import org.elasticsearch.index.query.TermsFilterBuilder;
037import org.elasticsearch.search.aggregations.AggregationBuilders;
038import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
039import org.elasticsearch.search.aggregations.bucket.terms.Terms;
040import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
041import org.nuxeo.ecm.core.api.DocumentModel;
042import org.nuxeo.ecm.platform.query.api.AggregateDefinition;
043import org.nuxeo.ecm.platform.query.core.BucketTerm;
044
045/**
046 * @since 6.0
047 */
048public class TermAggregate extends AggregateEsBase<BucketTerm> {
049
050    public TermAggregate(AggregateDefinition definition, DocumentModel searchDocument) {
051        super(definition, searchDocument);
052    }
053
054    @JsonIgnore
055    @Override
056    public TermsBuilder getEsAggregate() {
057        TermsBuilder ret = AggregationBuilders.terms(getId()).field(getField());
058        Map<String, String> props = getProperties();
059        if (props.containsKey(AGG_SIZE_PROP)) {
060            ret.size(Integer.parseInt(props.get(AGG_SIZE_PROP)));
061        }
062        if (props.containsKey(AGG_MIN_DOC_COUNT_PROP)) {
063            ret.minDocCount(Long.parseLong(props.get(AGG_MIN_DOC_COUNT_PROP)));
064        }
065        if (props.containsKey(AGG_EXCLUDE_PROP)) {
066            ret.exclude(props.get(AGG_EXCLUDE_PROP));
067        }
068        if (props.containsKey(AGG_INCLUDE_PROP)) {
069            ret.include(props.get(AGG_INCLUDE_PROP));
070        }
071        if (props.containsKey(AGG_ORDER_PROP)) {
072            switch (props.get(AGG_ORDER_PROP).toLowerCase()) {
073            case AGG_ORDER_COUNT_DESC:
074                ret.order(Terms.Order.count(false));
075                break;
076            case AGG_ORDER_COUNT_ASC:
077                ret.order(Terms.Order.count(true));
078                break;
079            case AGG_ORDER_TERM_DESC:
080                ret.order(Terms.Order.term(false));
081                break;
082            case AGG_ORDER_TERM_ASC:
083                ret.order(Terms.Order.term(true));
084                break;
085            default:
086                throw new IllegalArgumentException("Invalid order: " + props.get(AGG_ORDER_PROP));
087            }
088        }
089        return ret;
090    }
091
092    @JsonIgnore
093    @Override
094    public TermsFilterBuilder getEsFilter() {
095        if (getSelection().isEmpty()) {
096            return null;
097        }
098        return FilterBuilders.termsFilter(getField(), getSelection());
099    }
100
101    @JsonIgnore
102    @Override
103    public void parseEsBuckets(Collection<? extends MultiBucketsAggregation.Bucket> buckets) {
104        List<BucketTerm> nxBuckets = new ArrayList<>(buckets.size());
105        for (MultiBucketsAggregation.Bucket bucket : buckets) {
106            nxBuckets.add(new BucketTerm(bucket.getKey(), bucket.getDocCount()));
107        }
108        this.buckets = nxBuckets;
109    }
110}