You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2015/06/29 10:30:14 UTC

svn commit: r1688122 - in /james/mailbox/trunk/elasticsearch/src: main/java/org/apache/james/mailbox/elasticsearch/query/ test/java/org/apache/james/mailbox/elasticsearch/query/

Author: btellier
Date: Mon Jun 29 08:30:14 2015
New Revision: 1688122

URL: http://svn.apache.org/r1688122
Log:
MAILBOX-235 rework Collector so that everything is immutable - patch contributed by Matthieu Baechlor

Modified:
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollector.java
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryRepresentation.java
    james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java
    james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollectorTest.java
    james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/QueryConverterTest.java

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java?rev=1688122&r1=1688121&r2=1688122&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java Mon Jun 29 08:30:14 2015
@@ -140,7 +140,7 @@ public class CriterionConverter {
     private FilteredQueryRepresentation convertConjunction(SearchQuery.ConjunctionCriterion criterion) {
         return criterion.getCriteria().stream()
             .map(this::convertCriterion)
-            .collect(new FilteredQueryCollector(criterion.getType()));
+            .collect(FilteredQueryCollector.collector(criterion.getType()));
     }
 
     private FilteredQueryRepresentation convertFlag(SearchQuery.FlagCriterion flagCriterion) {
@@ -192,7 +192,7 @@ public class CriterionConverter {
         }
         return Arrays.stream(uidCriterion.getOperator().getRange())
             .map(this::uidRangeFilter)
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.OR));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
     }
 
     private FilteredQueryRepresentation uidRangeFilter(SearchQuery.NumericRange numericRange) {

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollector.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollector.java?rev=1688122&r1=1688121&r2=1688122&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollector.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollector.java Mon Jun 29 08:30:14 2015
@@ -19,105 +19,19 @@
 
 package org.apache.james.mailbox.elasticsearch.query;
 
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.FilterBuilders.boolFilter;
-
-import org.apache.james.mailbox.model.SearchQuery;
-import org.elasticsearch.index.query.BoolFilterBuilder;
-import org.elasticsearch.index.query.BoolQueryBuilder;
-
-import java.util.EnumSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BiConsumer;
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.Supplier;
 import java.util.stream.Collector;
+import java.util.stream.Collectors;
 
-public class FilteredQueryCollector implements Collector<FilteredQueryRepresentation, FilteredQueryRepresentation, FilteredQueryRepresentation> {
-
-    private final SearchQuery.Conjunction type;
-
-    public FilteredQueryCollector(SearchQuery.Conjunction type) {
-        this.type = type;
-    }
-
-    @Override
-    public Supplier<FilteredQueryRepresentation> supplier() {
-        return FilteredQueryRepresentation::empty;
-    }
-
-    @Override
-    public BiConsumer<FilteredQueryRepresentation, FilteredQueryRepresentation> accumulator() {
-        return this::apply;
-    }
-
-    @Override
-    public BinaryOperator<FilteredQueryRepresentation> combiner() {
-        return this::apply;
-    }
-
-    @Override
-    public Function<FilteredQueryRepresentation, FilteredQueryRepresentation> finisher() {
-        return (accumulator)->accumulator;
-    }
-
-    @Override
-    public Set<Characteristics> characteristics() {
-        return EnumSet.of(Characteristics.UNORDERED);
-    }
-
-    private FilteredQueryRepresentation apply(FilteredQueryRepresentation accumulator, FilteredQueryRepresentation collected) {
-        initializeAccumulatorWhenNeeded(accumulator, collected);
-        switch (type) {
-        case OR:
-            return applyOr(accumulator, collected);
-        case AND:
-            return applyAnd(accumulator, collected);
-        case NOR:
-            return applyNor(accumulator, collected);
-        }
-        return accumulator;
-    }
+import org.apache.james.mailbox.model.SearchQuery;
 
-    private void initializeAccumulatorWhenNeeded(FilteredQueryRepresentation accumulator, FilteredQueryRepresentation collected) {
-        // This method is compulsory because elasticSearch refuses to build empty BoolQuery and empty BoolFilter
-        if (!accumulator.getQuery().isPresent() && collected.getQuery().isPresent()) {
-            accumulator.setQuery(Optional.of(boolQuery()));
-        }
-        if (!accumulator.getFilter().isPresent() && collected.getFilter().isPresent()) {
-            accumulator.setFilter(Optional.of(boolFilter()));
-        }
-    }
+public class FilteredQueryCollector {
 
-    private FilteredQueryRepresentation applyNor(FilteredQueryRepresentation accumulator, FilteredQueryRepresentation collected) {
-        if (collected.getQuery().isPresent()) {
-            ((BoolQueryBuilder) accumulator.getQuery().get()).mustNot(collected.getQuery().get());
-        }
-        if (collected.getFilter().isPresent()) {
-            ((BoolFilterBuilder) accumulator.getFilter().get()).mustNot(collected.getFilter().get());
-        }
-        return accumulator;
+    public static Collector<FilteredQueryRepresentation, ?, FilteredQueryRepresentation> 
+        collector(SearchQuery.Conjunction type) {
+        
+        return Collectors.reducing(
+                FilteredQueryRepresentation.empty(),
+                (x, y) -> x.combine(type, y));
     }
 
-    private FilteredQueryRepresentation applyAnd(FilteredQueryRepresentation accumulator, FilteredQueryRepresentation collected) {
-        if (collected.getQuery().isPresent()) {
-            ((BoolQueryBuilder) accumulator.getQuery().get()).must(collected.getQuery().get());
-        }
-        if (collected.getFilter().isPresent()) {
-            ((BoolFilterBuilder) accumulator.getFilter().get()).must(collected.getFilter().get());
-        }
-        return accumulator;
-    }
-
-    private FilteredQueryRepresentation applyOr(FilteredQueryRepresentation accumulator, FilteredQueryRepresentation collected) {
-        if (collected.getQuery().isPresent()) {
-            ((BoolQueryBuilder) accumulator.getQuery().get()).should(collected.getQuery().get());
-        }
-        if (collected.getFilter().isPresent()) {
-            ((BoolFilterBuilder) accumulator.getFilter().get()).should(collected.getFilter().get());
-        }
-        return accumulator;
-    }
 }

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryRepresentation.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryRepresentation.java?rev=1688122&r1=1688121&r2=1688122&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryRepresentation.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryRepresentation.java Mon Jun 29 08:30:14 2015
@@ -19,10 +19,17 @@
 
 package org.apache.james.mailbox.elasticsearch.query;
 
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.apache.james.mailbox.model.SearchQuery;
+import org.elasticsearch.index.query.BoolFilterBuilder;
+import org.elasticsearch.index.query.BoolQueryBuilder;
 import org.elasticsearch.index.query.FilterBuilder;
+import org.elasticsearch.index.query.FilterBuilders;
 import org.elasticsearch.index.query.QueryBuilder;
-
-import java.util.Optional;
+import org.elasticsearch.index.query.QueryBuilders;
 
 public  class FilteredQueryRepresentation {
 
@@ -38,8 +45,8 @@ public  class FilteredQueryRepresentatio
         return new FilteredQueryRepresentation(Optional.empty(), Optional.empty());
     }
 
-    private Optional<FilterBuilder> filter;
-    private Optional<QueryBuilder> query;
+    private final Optional<FilterBuilder> filter;
+    private final Optional<QueryBuilder> query;
 
     private FilteredQueryRepresentation(Optional<QueryBuilder> query, Optional<FilterBuilder> filter) {
         this.query = query;
@@ -54,11 +61,90 @@ public  class FilteredQueryRepresentatio
         return query;
     }
 
-    public void setFilter(Optional<FilterBuilder> filter) {
-        this.filter = filter;
+    public FilteredQueryRepresentation combine(SearchQuery.Conjunction type, FilteredQueryRepresentation collected) {
+        switch (type) {
+        case OR:
+            return applyOr(collected);
+        case AND:
+            return applyAnd(collected);
+        case NOR:
+            return new FilteredQueryRepresentation(
+                applyNorOnQuery(collected),
+                applyNorOnFilter(collected));
+        }
+        return this;
+    }
+    
+    private FilteredQueryRepresentation applyAnd(FilteredQueryRepresentation collected) {
+        return new FilteredQueryRepresentation(
+                applyOnQuery(
+                    (x, y) -> x.must(y),
+                    collected.getQuery(),
+                    (x) -> QueryBuilders.boolQuery().must(x)),
+                applyOnFilter(
+                    (x, y) -> x.must(y),
+                    collected.getFilter(),
+                    (x) -> FilterBuilders.boolFilter().must(x)));
+    }
+
+    private FilteredQueryRepresentation applyOr(FilteredQueryRepresentation collected) {
+        return new FilteredQueryRepresentation(
+            applyOnQuery(
+                (x, y) -> x.should(y),
+                collected.getQuery(),
+                (x) -> QueryBuilders.boolQuery().should(x)),
+            applyOnFilter(
+                (x, y) -> x.should(y),
+                collected.getFilter(),
+                (x) -> FilterBuilders.boolFilter().should(x)));
+    }
+
+    private Optional<QueryBuilder> applyOnQuery(BiFunction<BoolQueryBuilder, QueryBuilder, QueryBuilder> function, Optional<QueryBuilder> input, Function<QueryBuilder, BoolQueryBuilder> s) {
+        return genericApply(ensureBoolQuery(function, s), query, input);
+    }
+
+    private BiFunction<QueryBuilder, QueryBuilder, QueryBuilder> 
+        ensureBoolQuery(BiFunction<BoolQueryBuilder, QueryBuilder, QueryBuilder> f, Function<QueryBuilder, BoolQueryBuilder> s) {
+        return (x, y) -> f.apply(s.apply(x), y);
+    }
+    
+    private Optional<FilterBuilder> applyOnFilter(BiFunction<BoolFilterBuilder, FilterBuilder, FilterBuilder> function, Optional<FilterBuilder> input, Function<FilterBuilder, BoolFilterBuilder> s) {
+        return genericApply(ensureBoolFilter(function, s), filter, input);
+    }
+
+    private BiFunction<FilterBuilder, FilterBuilder, FilterBuilder> 
+        ensureBoolFilter(BiFunction<BoolFilterBuilder, FilterBuilder, FilterBuilder> f, Function<FilterBuilder, BoolFilterBuilder> s) {
+        return (x, y) -> f.apply(s.apply(x), y);
+    }
+    
+    private <T> Optional<T> genericApply(BiFunction<T, T, T> function, Optional<T> lhs, Optional<T> rhs) {
+        if (rhs.isPresent()) {
+            if (lhs.isPresent()) {
+                return Optional.of(function.apply(rhs.get(), lhs.get()));
+            } else {
+                return rhs;
+            }
+        } else {
+            return lhs;
+        }
+    }
+
+    private Optional<FilterBuilder> applyNorOnFilter(FilteredQueryRepresentation collected) {
+        // The cast is necessary for determining types ( in other cases : Optional<BoolFilterBuilder> is incompatible with Optional<FilterBuilder>
+        return collected.getFilter().map(
+            (collectedFilter) -> filter.map(
+                (innerFilter) -> Optional.of((FilterBuilder) FilterBuilders.boolFilter().must(innerFilter).mustNot(collectedFilter)))
+                    .orElse(Optional.of(FilterBuilders.boolFilter().mustNot(collectedFilter)))
+        ).orElse(filter);
+    }
+
+    private Optional<QueryBuilder> applyNorOnQuery(FilteredQueryRepresentation collected) {
+        // The cast is necessary for determining types ( in other cases : Optional<BoolQueryBuilder> is incompatible with Optional<QueryBuilder>
+        return collected.getQuery().map(
+            (collectedQuery) -> query.map(
+                (innerQuery) -> Optional.of((QueryBuilder)QueryBuilders.boolQuery().must(innerQuery).mustNot(collected.getQuery().get())))
+                    .orElse(Optional.of(QueryBuilders.boolQuery().mustNot(collectedQuery)))
+        ).orElse(query);
     }
 
-    public void setQuery(Optional<QueryBuilder> query) {
-        this.query = query;
-    }
 }

Modified: james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java?rev=1688122&r1=1688121&r2=1688122&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java (original)
+++ james/mailbox/trunk/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/QueryConverter.java Mon Jun 29 08:30:14 2015
@@ -67,7 +67,7 @@ public class QueryConverter implements F
     private FilteredQueryRepresentation addMailboxFilters(FilteredQueryRepresentation elasticsearchQueryRepresentation, String mailboxUUID) {
         return Stream.of(elasticsearchQueryRepresentation,
             FilteredQueryRepresentation.fromFilter(termFilter(JsonMessageConstants.MAILBOX_ID, mailboxUUID)))
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
     }
 
     private QueryBuilder getFinalQuery(FilteredQueryRepresentation filteredQueryRepresentation) {

Modified: james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollectorTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollectorTest.java?rev=1688122&r1=1688121&r2=1688122&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollectorTest.java (original)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/FilteredQueryCollectorTest.java Mon Jun 29 08:30:14 2015
@@ -40,7 +40,7 @@ public class FilteredQueryCollectorTest
         List<FilteredQueryRepresentation> emptyFilteredQueryRepresentationList = Lists.newArrayList();
         FilteredQueryRepresentation collectionResult = emptyFilteredQueryRepresentationList
             .stream()
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
         assertThat(collectionResult.getFilter()).isEmpty();
         assertThat(collectionResult.getQuery()).isEmpty();
     }
@@ -48,21 +48,21 @@ public class FilteredQueryCollectorTest
     @Test
     public void queryAloneShouldBeWellCollected() throws Exception {
         FilteredQueryRepresentation collectionResult = Stream.of(FilteredQueryRepresentation.fromQuery(matchAllQuery()))
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
         assertThat(collectionResult.getFilter()).isEmpty();
         assertThat(collectionResult.getQuery()).isPresent();
         assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
-            .isEqualTo("{\"bool\":{\"must\":{\"match_all\":{}}}}");
+            .isEqualTo("{\"match_all\":{}}");
     }
 
     @Test
     public void filterAloneShouldBeWellCollected() throws Exception {
         FilteredQueryRepresentation collectionResult = Stream.of(FilteredQueryRepresentation.fromFilter(termFilter("field", "value")))
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
         assertThat(collectionResult.getFilter()).isPresent();
         assertThat(collectionResult.getQuery()).isEmpty();
         assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
-            .isEqualTo("{\"bool\":{\"must\":{\"term\":{\"field\":\"value\"}}}}");
+            .isEqualTo("{\"term\":{\"field\":\"value\"}}");
     }
 
     @Test
@@ -70,13 +70,13 @@ public class FilteredQueryCollectorTest
         FilteredQueryRepresentation collectionResult = Stream.of(
             FilteredQueryRepresentation.fromFilter(termFilter("field", "value")),
             FilteredQueryRepresentation.fromQuery(matchAllQuery()))
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
         assertThat(collectionResult.getFilter()).isPresent();
         assertThat(collectionResult.getQuery()).isPresent();
         assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
-            .isEqualTo("{\"bool\":{\"must\":{\"match_all\":{}}}}");
+            .isEqualTo("{\"match_all\":{}}");
         assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
-            .isEqualTo("{\"bool\":{\"must\":{\"term\":{\"field\":\"value\"}}}}");
+            .isEqualTo("{\"term\":{\"field\":\"value\"}}");
     }
 
     @Test
@@ -84,7 +84,7 @@ public class FilteredQueryCollectorTest
         FilteredQueryRepresentation collectionResult = Stream.of(
             FilteredQueryRepresentation.fromQuery(matchAllQuery()),
             FilteredQueryRepresentation.fromQuery(matchAllQuery()))
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
         assertThat(collectionResult.getFilter()).isEmpty();
         assertThat(collectionResult.getQuery()).isPresent();
         assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
@@ -96,11 +96,148 @@ public class FilteredQueryCollectorTest
         FilteredQueryRepresentation collectionResult = Stream.of(
             FilteredQueryRepresentation.fromFilter(termFilter("field", "value")),
             FilteredQueryRepresentation.fromFilter(termFilter("field", "value")))
-            .collect(new FilteredQueryCollector(SearchQuery.Conjunction.AND));
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.AND));
         assertThat(collectionResult.getFilter()).isPresent();
         assertThat(collectionResult.getQuery()).isEmpty();
         assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
             .isEqualTo("{\"bool\":{\"must\":[{\"term\":{\"field\":\"value\"}},{\"term\":{\"field\":\"value\"}}]}}");
     }
 
+    @Test
+    public void emptyStreamShouldBeCollectedAsEmptyFilteredQueryRepresentationOnNor() throws Exception {
+        List<FilteredQueryRepresentation> emptyFilteredQueryRepresentationList = Lists.newArrayList();
+        FilteredQueryRepresentation collectionResult = emptyFilteredQueryRepresentationList
+            .stream()
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.NOR));
+        assertThat(collectionResult.getFilter()).isEmpty();
+        assertThat(collectionResult.getQuery()).isEmpty();
+    }
+
+    @Test
+    public void queryAloneShouldBeWellCollectedOnNor() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(FilteredQueryRepresentation.fromQuery(matchAllQuery()))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.NOR));
+        assertThat(collectionResult.getFilter()).isEmpty();
+        assertThat(collectionResult.getQuery()).isPresent();
+        assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"must_not\":{\"match_all\":{}}}}");
+    }
+
+    @Test
+    public void filterAloneShouldBeWellCollectedOnNor() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(FilteredQueryRepresentation.fromFilter(termFilter("field", "value")))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.NOR));
+        assertThat(collectionResult.getFilter()).isPresent();
+        assertThat(collectionResult.getQuery()).isEmpty();
+        assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"must_not\":{\"term\":{\"field\":\"value\"}}}}");
+    }
+
+    @Test
+    public void aggregationBetweenQueryAndFilterShouldWorkOnNor() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(
+            FilteredQueryRepresentation.fromFilter(termFilter("field", "value")),
+            FilteredQueryRepresentation.fromQuery(matchAllQuery()))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.NOR));
+        assertThat(collectionResult.getFilter()).isPresent();
+        assertThat(collectionResult.getQuery()).isPresent();
+        assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"must_not\":{\"match_all\":{}}}}");
+        assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"must_not\":{\"term\":{\"field\":\"value\"}}}}");
+    }
+
+    @Test
+    public void queryAggregationShouldWorkOnNor() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(
+            FilteredQueryRepresentation.fromQuery(matchAllQuery()),
+            FilteredQueryRepresentation.fromQuery(matchAllQuery()))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.NOR));
+        assertThat(collectionResult.getFilter()).isEmpty();
+        assertThat(collectionResult.getQuery()).isPresent();
+        assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"must\":{\"bool\":{\"must_not\":{\"match_all\":{}}}},\"must_not\":{\"match_all\":{}}}}");
+    }
+
+    @Test
+    public void filterAggregationShouldWorkOnNor() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(
+            FilteredQueryRepresentation.fromFilter(termFilter("field", "value")),
+            FilteredQueryRepresentation.fromFilter(termFilter("field", "value")))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.NOR));
+        assertThat(collectionResult.getFilter()).isPresent();
+        assertThat(collectionResult.getQuery()).isEmpty();
+        assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo(
+                "{\"bool\":{\"must\":{\"bool\":{\"must_not\":{\"term\":{\"field\":\"value\"}}}},\"must_not\":{\"term\":{\"field\":\"value\"}}}}");
+    }
+
+    @Test
+    public void emptyStreamShouldBeCollectedAsEmptyFilteredQueryRepresentationOnOr() throws Exception {
+        List<FilteredQueryRepresentation> emptyFilteredQueryRepresentationList = Lists.newArrayList();
+        FilteredQueryRepresentation collectionResult = emptyFilteredQueryRepresentationList
+            .stream()
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
+        assertThat(collectionResult.getFilter()).isEmpty();
+        assertThat(collectionResult.getQuery()).isEmpty();
+    }
+
+    @Test
+    public void queryAloneShouldBeWellCollectedOnOr() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(FilteredQueryRepresentation.fromQuery(matchAllQuery()))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
+        assertThat(collectionResult.getFilter()).isEmpty();
+        assertThat(collectionResult.getQuery()).isPresent();
+        assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"match_all\":{}}");
+    }
+
+    @Test
+    public void filterAloneShouldBeWellCollectedOnOr() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(FilteredQueryRepresentation.fromFilter(termFilter("field", "value")))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
+        assertThat(collectionResult.getFilter()).isPresent();
+        assertThat(collectionResult.getQuery()).isEmpty();
+        assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"term\":{\"field\":\"value\"}}");
+    }
+
+    @Test
+    public void aggregationBetweenQueryAndFilterShouldWorkOnOr() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(
+            FilteredQueryRepresentation.fromFilter(termFilter("field", "value")),
+            FilteredQueryRepresentation.fromQuery(matchAllQuery()))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
+        assertThat(collectionResult.getFilter()).isPresent();
+        assertThat(collectionResult.getQuery()).isPresent();
+        assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"match_all\":{}}");
+        assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"term\":{\"field\":\"value\"}}");
+    }
+
+    @Test
+    public void queryAggregationShouldWorkOnOr() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(
+            FilteredQueryRepresentation.fromQuery(matchAllQuery()),
+            FilteredQueryRepresentation.fromQuery(matchAllQuery()))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
+        assertThat(collectionResult.getFilter()).isEmpty();
+        assertThat(collectionResult.getQuery()).isPresent();
+        assertThatJson(collectionResult.getQuery().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"should\":[{\"match_all\":{}},{\"match_all\":{}}]}}");
+    }
+
+    @Test
+    public void filterAggregationShouldWorkOnOr() throws Exception {
+        FilteredQueryRepresentation collectionResult = Stream.of(
+            FilteredQueryRepresentation.fromFilter(termFilter("field", "value")),
+            FilteredQueryRepresentation.fromFilter(termFilter("field", "value")))
+            .collect(FilteredQueryCollector.collector(SearchQuery.Conjunction.OR));
+        assertThat(collectionResult.getFilter()).isPresent();
+        assertThat(collectionResult.getQuery()).isEmpty();
+        assertThatJson(collectionResult.getFilter().get().toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .isEqualTo("{\"bool\":{\"should\":[{\"term\":{\"field\":\"value\"}},{\"term\":{\"field\":\"value\"}}]}}");
+    }
+
 }

Modified: james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/QueryConverterTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/QueryConverterTest.java?rev=1688122&r1=1688121&r2=1688122&view=diff
==============================================================================
--- james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/QueryConverterTest.java (original)
+++ james/mailbox/trunk/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/query/QueryConverterTest.java Mon Jun 29 08:30:14 2015
@@ -48,27 +48,19 @@ public class QueryConverterTest {
         SearchQuery searchQuery = new SearchQuery();
         searchQuery.andCriteria(SearchQuery.all());
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID).toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "    \"filtered\": {" +
                 "        \"query\": {" +
-                "            \"bool\": {" +
-                "                \"must\": {" +
                 "                    \"match_all\": {}" +
-                "                }" +
-                "            }" +
                 "        }," +
                 "        \"filter\": {" +
-                "            \"bool\": {" +
-                "                \"must\": {" +
                 "                    \"term\": {" +
                 "                        \"mailboxId\": \"12345\"" +
                 "                    }" +
-                "                }" +
-                "            }" +
                 "        }" +
                 "    }" +
-                "}")
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
     }
 
     @Test
@@ -76,32 +68,24 @@ public class QueryConverterTest {
         SearchQuery searchQuery = new SearchQuery();
         searchQuery.andCriteria(SearchQuery.bodyContains("awesome Linagora team"));
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID).toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "    \"filtered\": {" +
                 "        \"query\": {" +
-                "            \"bool\": {" +
-                "                \"must\": {" +
                 "                    \"match\": {" +
                 "                        \"textBody\": {" +
                 "                            \"query\": \"awesome Linagora team\"," +
                 "                            \"type\": \"boolean\"" +
                 "                        }" +
-                "                    }" +
-                "                }" +
                 "            }" +
                 "        }," +
                 "        \"filter\": {" +
-                "            \"bool\": {" +
-                "                \"must\": {" +
                 "                    \"term\": {" +
                 "                        \"mailboxId\": \"12345\"" +
                 "                    }" +
-                "                }" +
-                "            }" +
                 "        }" +
                 "    }" +
-                "}")
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
     }
 
     @Test
@@ -109,6 +93,7 @@ public class QueryConverterTest {
         SearchQuery searchQuery = new SearchQuery();
         searchQuery.andCriteria(SearchQuery.modSeqGreaterThan(42L));
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID).toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "  \"filtered\" : {" +
                 "    \"query\" : {" +
@@ -133,8 +118,7 @@ public class QueryConverterTest {
                 "      }" +
                 "    }" +
                 "  }" +
-                "}")
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
     }
 
     @Test
@@ -143,11 +127,10 @@ public class QueryConverterTest {
         searchQuery.andCriteria(SearchQuery.bodyContains("awesome Linagora team"));
         searchQuery.andCriteria(SearchQuery.bodyContains("Gold fish"));
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID).toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "    \"filtered\": {" +
                 "        \"query\": {" +
-                "            \"bool\": {" +
-                "                \"must\": {" +
                 "                    \"bool\": {" +
                 "                        \"must\": [" +
                 "                            {" +
@@ -167,22 +150,15 @@ public class QueryConverterTest {
                 "                                }" +
                 "                            }" +
                 "                        ]" +
-                "                    }" +
-                "                }" +
                 "            }" +
                 "        }," +
                 "        \"filter\": {" +
-                "            \"bool\": {" +
-                "                \"must\": {" +
                 "                    \"term\": {" +
                 "                        \"mailboxId\": \"12345\"" +
                 "                    }" +
-                "                }" +
-                "            }" +
                 "        }" +
                 "    }" +
-                "}")
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
     }
 
     @Test
@@ -190,6 +166,7 @@ public class QueryConverterTest {
         SearchQuery searchQuery = new SearchQuery();
         searchQuery.andCriteria(SearchQuery.modSeqGreaterThan(42L));
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID + "\"},{\"exist\":\"id\"},{\"match\":\"well done").toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "  \"filtered\" : {" +
                 "    \"query\" : {" +
@@ -214,8 +191,7 @@ public class QueryConverterTest {
                 "      }" +
                 "    }" +
                 "  }" +
-                "}")
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
     }
 
     @Test
@@ -223,48 +199,40 @@ public class QueryConverterTest {
         SearchQuery searchQuery = new SearchQuery();
         searchQuery.andCriteria(SearchQuery.address(SearchQuery.AddressType.Bcc, "Benoit Tellier<bt...@free.fr>"));
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID).toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "  \"filtered\" : {" +
                 "    \"query\" : {" +
-                "      \"bool\" : {" +
-                "        \"must\" : {" +
-                "          \"nested\" : {" +
-                "            \"query\" : {" +
-                "              \"bool\" : {" +
-                "                \"should\" : [ {" +
-                "                  \"match\" : {" +
-                "                    \"bcc.name\" : {" +
-                "                      \"query\" : \"Benoit Tellier<bt...@free.fr>\"," +
-                "                      \"type\" : \"boolean\"" +
-                "                    }" +
-                "                  }" +
-                "                }, {" +
-                "                  \"match\" : {" +
-                "                    \"bcc.address\" : {" +
-                "                      \"query\" : \"Benoit Tellier<bt...@free.fr>\"," +
-                "                      \"type\" : \"boolean\"" +
-                "                    }" +
-                "                  }" +
-                "                } ]" +
+                "      \"nested\" : {" +
+                "        \"query\" : {" +
+                "          \"bool\" : {" +
+                "            \"should\" : [ {" +
+                "              \"match\" : {" +
+                "                \"bcc.name\" : {" +
+                "                  \"query\" : \"Benoit Tellier<bt...@free.fr>\"," +
+                "                  \"type\" : \"boolean\"" +
+                "                }" +
+                "              }" +
+                "            }, {" +
+                "              \"match\" : {" +
+                "                \"bcc.address\" : {" +
+                "                  \"query\" : \"Benoit Tellier<bt...@free.fr>\"," +
+                "                  \"type\" : \"boolean\"" +
+                "                }" +
                 "              }" +
-                "            }," +
-                "            \"path\" : \"bcc\"" +
+                "            } ]" +
                 "          }" +
-                "        }" +
+                "        }," +
+                "        \"path\" : \"bcc\"" +
                 "      }" +
                 "    }," +
                 "    \"filter\" : {" +
-                "      \"bool\" : {" +
-                "        \"must\" : {" +
-                "          \"term\" : {" +
-                "            \"mailboxId\" : \"12345\"" +
-                "          }" +
-                "        }" +
+                "      \"term\" : {" +
+                "        \"mailboxId\" : \"12345\"" +
                 "      }" +
                 "    }" +
                 "  }" +
-                "}")
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
     }
 
     @Test
@@ -275,6 +243,8 @@ public class QueryConverterTest {
             new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2015-02-25 21:54:38"),
             SearchQuery.DateResolution.Hour));
         assertThatJson(queryConverter.from(searchQuery, MAILBOX_UUID).toXContent(jsonBuilder(), QueryBuilder.EMPTY_PARAMS).string())
+            .when(IGNORING_VALUES)
+            .when(IGNORING_ARRAY_ORDER)
             .isEqualTo("{" +
                 "    \"filtered\": {" +
                 "        \"query\": {" +
@@ -302,9 +272,7 @@ public class QueryConverterTest {
                 "            }" +
                 "        }" +
                 "    }" +
-                "}")
-            .when(IGNORING_VALUES)
-            .when(IGNORING_ARRAY_ORDER);
+                "}");
         // We just test structure as time Zone used by Date is different, depending on computer configuration
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org