001/*
002 * (C) Copyright 2014 Nuxeo SA (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 *     bdelbosc
018 */
019package org.nuxeo.elasticsearch.aggregate;
020
021import static org.nuxeo.elasticsearch.ElasticSearchConstants.AGG_FORMAT_PROP;
022
023import java.util.ArrayList;
024import java.util.Collection;
025import java.util.Collections;
026import java.util.Comparator;
027import java.util.List;
028import java.util.Map;
029
030import org.codehaus.jackson.annotate.JsonIgnore;
031import org.elasticsearch.index.query.FilterBuilders;
032import org.elasticsearch.index.query.OrFilterBuilder;
033import org.elasticsearch.index.query.RangeFilterBuilder;
034import org.elasticsearch.search.aggregations.AggregationBuilders;
035import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
036import org.elasticsearch.search.aggregations.bucket.range.date.DateRange;
037import org.elasticsearch.search.aggregations.bucket.range.date.DateRangeBuilder;
038import org.nuxeo.ecm.core.api.DocumentModel;
039import org.nuxeo.ecm.platform.query.api.AggregateDefinition;
040import org.nuxeo.ecm.platform.query.api.AggregateRangeDateDefinition;
041import org.nuxeo.ecm.platform.query.core.BucketRangeDate;
042
043/**
044 * @since 6.0
045 */
046public class DateRangeAggregate extends AggregateEsBase<BucketRangeDate> {
047
048    public DateRangeAggregate(AggregateDefinition definition, DocumentModel searchDocument) {
049        super(definition, searchDocument);
050    }
051
052    @JsonIgnore
053    @Override
054    public DateRangeBuilder getEsAggregate() {
055        DateRangeBuilder ret = AggregationBuilders.dateRange(getId()).field(getField());
056        for (AggregateRangeDateDefinition range : getDateRanges()) {
057            if (range.getFromAsString() != null) {
058                if (range.getToAsString() != null) {
059                    ret.addRange(range.getKey(), range.getFromAsString(), range.getToAsString());
060                } else {
061                    ret.addUnboundedFrom(range.getKey(), range.getFromAsString());
062                }
063            } else if (range.getToAsString() != null) {
064                ret.addUnboundedTo(range.getKey(), range.getToAsString());
065            }
066        }
067        Map<String, String> props = getProperties();
068        if (props.containsKey(AGG_FORMAT_PROP)) {
069            ret.format(props.get(AGG_FORMAT_PROP));
070        }
071        return ret;
072    }
073
074    @JsonIgnore
075    @Override
076    public OrFilterBuilder getEsFilter() {
077        if (getSelection().isEmpty()) {
078            return null;
079        }
080        OrFilterBuilder ret = FilterBuilders.orFilter();
081        for (AggregateRangeDateDefinition range : getDateRanges()) {
082            if (getSelection().contains(range.getKey())) {
083                RangeFilterBuilder rangeFilter = FilterBuilders.rangeFilter(getField());
084                if (range.getFromAsString() != null) {
085                    rangeFilter.gte(range.getFromAsString());
086                }
087                if (range.getToAsString() != null) {
088                    rangeFilter.lt(range.getToAsString());
089                }
090                ret.add(rangeFilter);
091            }
092        }
093        return ret;
094    }
095
096    @JsonIgnore
097    @Override
098    public void parseEsBuckets(Collection<? extends MultiBucketsAggregation.Bucket> buckets) {
099        List<BucketRangeDate> nxBuckets = new ArrayList<>(buckets.size());
100        for (MultiBucketsAggregation.Bucket bucket : buckets) {
101            DateRange.Bucket rangeBucket = (DateRange.Bucket) bucket;
102            nxBuckets.add(new BucketRangeDate(bucket.getKey(), getDateTime(rangeBucket.getFromAsDate()),
103                    getDateTime(rangeBucket.getToAsDate()), rangeBucket.getDocCount()));
104        }
105        Collections.sort(nxBuckets, new BucketRangeDateComparator());
106        this.buckets = nxBuckets;
107    }
108
109    protected class BucketRangeDateComparator implements Comparator<BucketRangeDate> {
110        @Override
111        public int compare(BucketRangeDate arg0, BucketRangeDate arg1) {
112            return definition.getAggregateDateRangeDefinitionOrderMap().get(arg0.getKey()).compareTo(
113                    definition.getAggregateDateRangeDefinitionOrderMap().get(arg1.getKey()));
114        }
115    }
116
117}