001/* 002 * (C) Copyright 2014-2016 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 java.util.ArrayList; 022import java.util.Collection; 023import java.util.Comparator; 024import java.util.List; 025 026import org.elasticsearch.index.query.BoolQueryBuilder; 027import org.elasticsearch.index.query.QueryBuilder; 028import org.elasticsearch.index.query.QueryBuilders; 029import org.elasticsearch.index.query.RangeQueryBuilder; 030import org.elasticsearch.search.aggregations.AggregationBuilders; 031import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation; 032import org.elasticsearch.search.aggregations.bucket.range.Range; 033import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder; 034import org.nuxeo.ecm.core.api.DocumentModel; 035import org.nuxeo.ecm.platform.query.api.AggregateDefinition; 036import org.nuxeo.ecm.platform.query.api.AggregateRangeDefinition; 037import org.nuxeo.ecm.platform.query.core.BucketRange; 038 039import com.fasterxml.jackson.annotation.JsonIgnore; 040 041/** 042 * @since 6.0 043 */ 044public class RangeAggregate extends MultiBucketAggregate<BucketRange> { 045 046 public RangeAggregate(AggregateDefinition definition, DocumentModel searchDocument) { 047 super(definition, searchDocument); 048 } 049 050 @JsonIgnore 051 @Override 052 public RangeAggregationBuilder getEsAggregate() { 053 RangeAggregationBuilder ret = AggregationBuilders.range(getId()).field(getField()); 054 for (AggregateRangeDefinition range : getRanges()) { 055 if (range.getFrom() != null) { 056 if (range.getTo() != null) { 057 ret.addRange(range.getKey(), range.getFrom(), range.getTo()); 058 } else { 059 ret.addUnboundedFrom(range.getKey(), range.getFrom()); 060 } 061 } else if (range.getTo() != null) { 062 ret.addUnboundedTo(range.getKey(), range.getTo()); 063 } 064 } 065 return ret; 066 } 067 068 @JsonIgnore 069 @Override 070 public QueryBuilder getEsFilter() { 071 if (getSelection().isEmpty()) { 072 return null; 073 } 074 BoolQueryBuilder ret = QueryBuilders.boolQuery(); 075 for (AggregateRangeDefinition range : getRanges()) { 076 if (getSelection().contains(range.getKey())) { 077 RangeQueryBuilder rangeFilter = QueryBuilders.rangeQuery(getField()); 078 if (range.getFrom() != null) { 079 rangeFilter.gte(range.getFrom()); 080 } 081 if (range.getTo() != null) { 082 rangeFilter.lt(range.getTo()); 083 } 084 ret.should(rangeFilter); 085 } 086 } 087 return ret; 088 } 089 090 @JsonIgnore 091 @Override 092 public void parseEsBuckets(Collection<? extends MultiBucketsAggregation.Bucket> buckets) { 093 List<BucketRange> nxBuckets = new ArrayList<>(buckets.size()); 094 for (MultiBucketsAggregation.Bucket bucket : buckets) { 095 Range.Bucket rangeBucket = (Range.Bucket) bucket; 096 double from = (double) rangeBucket.getFrom(); 097 double to = (double) rangeBucket.getTo(); 098 nxBuckets.add(new BucketRange(bucket.getKeyAsString(), from, to, rangeBucket.getDocCount())); 099 } 100 nxBuckets.sort(new BucketRangeComparator()); 101 this.buckets = nxBuckets; 102 } 103 104 protected class BucketRangeComparator implements Comparator<BucketRange> { 105 @Override 106 public int compare(BucketRange arg0, BucketRange arg1) { 107 return definition.getAggregateRangeDefinitionOrderMap() 108 .get(arg0.getKey()) 109 .compareTo(definition.getAggregateRangeDefinitionOrderMap().get(arg1.getKey())); 110 } 111 } 112 113}