From f5a04fb9fb01624e6280a2f4fca9d0ae5ccd79f0 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Thu, 10 Apr 2014 12:58:06 +0200 Subject: [PATCH] DATAMONGO-908 - Support for nested field references in group operations. We now allow referring to nested field expressions if the root segment of the nested field expression was exposed in earlier stages of the aggregation pipeline. Original pull request: #167. --- ...osedFieldsAggregationOperationContext.java | 16 +++++++++++++- .../aggregation/AggregationUnitTests.java | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java index 88590bed8..ca7d8db5b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFieldsAggregationOperationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,12 +69,26 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo @Override public FieldReference getReference(String name) { + Assert.notNull(name, "Name must not be null!"); + ExposedField field = exposedFields.getField(name); if (field != null) { return new FieldReference(field); } + if (name.contains(".")) { + + // for nested field references we only check that the root field exists. + ExposedField rootField = exposedFields.getField(name.split("\\.")[0]); + + if (rootField != null) { + + // We have to synthetic to true, in order to render the field-name as is. + return new FieldReference(new ExposedField(name, true)); + } + } + throw new IllegalArgumentException(String.format("Invalid reference '%s'!", name)); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java index dae68fda1..2012200e6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java @@ -179,4 +179,25 @@ public class AggregationUnitTests { DBObject fields = getAsDBObject(secondProjection, "$group"); assertThat(fields.get("foosum"), is((Object) new BasicDBObject("$sum", "$foo"))); } + + /** + * @see DATAMONGO-908 + */ + @Test + public void shouldSupportReferingToNestedPropertiesInGroupOperation() { + + DBObject agg = newAggregation( // + project("cmsParameterId", "rules"), // + unwind("rules"), // + group("cmsParameterId", "rules.ruleType").count().as("totol") // + ).toDbObject("foo", Aggregation.DEFAULT_CONTEXT); + + assertThat(agg, is(notNullValue())); + + DBObject group = ((List) agg.get("pipeline")).get(2); + DBObject fields = getAsDBObject(group, "$group"); + DBObject id = getAsDBObject(fields, "_id"); + + assertThat(id.get("ruleType"), is((Object) "$rules.ruleType")); + } }