DATAMONGO-2377 - Fix handling of $$value and $$this in field exposing aggregation.

Internal field references to $$this and $$value are now no longer mapped against exposed fields which had caused errors before.

Original pull request: #792.
This commit is contained in:
Christoph Strobl
2019-09-23 10:03:23 +02:00
committed by Mark Paluch
parent 0f0a4ed31b
commit 899b43a29b
4 changed files with 37 additions and 0 deletions

View File

@@ -69,6 +69,11 @@ class ExposedFieldsAggregationOperationContext implements AggregationOperationCo
*/
@Override
public FieldReference getReference(Field field) {
if(field.isInternal()) {
return new DirectFieldReference(new ExposedField(field, true));
}
return getReference(field, field.getTarget());
}

View File

@@ -43,4 +43,12 @@ public interface Field {
* @return
*/
boolean isAliased();
/**
* @return true if the field name references a local value such as {@code $$this}.
* @since 2.1.11
*/
default boolean isInternal() {
return false;
}
}

View File

@@ -283,6 +283,11 @@ public final class Fields implements Iterable<Field> {
return !getName().equals(getTarget());
}
@Override
public boolean isInternal() {
return getRaw().endsWith("$$this") || getRaw().endsWith("$$value");
}
/**
* @return {@literal true} in case the field name starts with {@code $$}.
* @since 1.10

View File

@@ -22,6 +22,7 @@ import static org.springframework.data.mongodb.test.util.Assertions.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.bson.Document;
@@ -569,6 +570,24 @@ public class AggregationUnitTests {
assertThat($project.containsKey("plts.ests")).isTrue();
}
@Test // DATAMONGO-2377
public void shouldAllowInternal$$thisAnd$$valueReferences() {
Document untyped = newAggregation( //
Arrays.asList( //
(group("uid", "data.sourceId") //
.push("data.attributeRecords").as("attributeRecordArrays")), //
(project() //
.and(ArrayOperators.arrayOf("attributeRecordArrays") //
.reduce(ArrayOperators.arrayOf("$$value").concat("$$this")) //
.startingWith(Collections.emptyList())) //
.as("attributeRecordArrays")) //
)).toDocument("collection-1", DEFAULT_CONTEXT);
assertThat(extractPipelineElement(untyped, 1, "$project")).isEqualTo(Document.parse(
"{\"attributeRecordArrays\": {\"$reduce\": {\"input\": \"$attributeRecordArrays\", \"initialValue\": [], \"in\": {\"$concatArrays\": [\"$$value\", \"$$this\"]}}}}"));
}
private Document extractPipelineElement(Document agg, int index, String operation) {
List<Document> pipeline = (List<Document>) agg.get("pipeline");