Compare commits
2 Commits
main
...
issue/4428
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd44432f81 | ||
|
|
f42e63d613 |
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.x-4428-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>Spring Data MongoDB</name>
|
<name>Spring Data MongoDB</name>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.x-4428-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.x-4428-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.x-4428-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,46 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
|||||||
return new ProjectionOperation(this.projections, projections);
|
return new ProjectionOperation(this.projections, projections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param path
|
||||||
|
* @return
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public ProjectionOperation andIncludePath(String path) {
|
||||||
|
return andIncludePaths(new String[] { path });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paths
|
||||||
|
* @return
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public ProjectionOperation andIncludePaths(String... paths) {
|
||||||
|
|
||||||
|
List<FieldProjection> projections = FieldProjection.from(Fields.fields(paths), 1);
|
||||||
|
return new ProjectionOperation(this.projections, projections);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param path
|
||||||
|
* @return
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public ProjectionOperation andExcludePath(String path) {
|
||||||
|
return andExcludePaths(new String[] { path });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paths
|
||||||
|
* @return
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public ProjectionOperation andExcludePaths(String... paths) {
|
||||||
|
|
||||||
|
List<FieldProjection> projections = FieldProjection.from(Fields.fields(paths), 0);
|
||||||
|
return new ProjectionOperation(this.projections, projections);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Includes the given fields into the projection.
|
* Includes the given fields into the projection.
|
||||||
*
|
*
|
||||||
@@ -495,8 +535,8 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
|||||||
if (value instanceof AggregationExpression) {
|
if (value instanceof AggregationExpression) {
|
||||||
return this.operation.and(new ExpressionProjection(Fields.field(alias, alias), (AggregationExpression) value));
|
return this.operation.and(new ExpressionProjection(Fields.field(alias, alias), (AggregationExpression) value));
|
||||||
}
|
}
|
||||||
|
Field field = Fields.field(alias, getRequiredName());
|
||||||
return this.operation.and(new FieldProjection(Fields.field(alias, getRequiredName()), null));
|
return this.operation.and(new FieldProjection(field, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1329,6 +1369,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
|||||||
|
|
||||||
private final Field field;
|
private final Field field;
|
||||||
private final @Nullable Object value;
|
private final @Nullable Object value;
|
||||||
|
private final ProjectOn projectOn;
|
||||||
|
|
||||||
|
enum ProjectOn {
|
||||||
|
PATH, NAME
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link FieldProjection} for the field of the given name, assigning the given value.
|
* Creates a new {@link FieldProjection} for the field of the given name, assigning the given value.
|
||||||
@@ -1341,11 +1386,16 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private FieldProjection(Field field, @Nullable Object value) {
|
private FieldProjection(Field field, @Nullable Object value) {
|
||||||
|
this(field, value, value instanceof Integer ? ProjectOn.PATH : ProjectOn.NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FieldProjection(Field field, @Nullable Object value, ProjectOn project) {
|
||||||
|
|
||||||
super(new ExposedField(field.getName(), true));
|
super(new ExposedField(field.getName(), true));
|
||||||
|
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.projectOn = project;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1372,7 +1422,8 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
|||||||
List<FieldProjection> projections = new ArrayList<FieldProjection>();
|
List<FieldProjection> projections = new ArrayList<FieldProjection>();
|
||||||
|
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
projections.add(new FieldProjection(field, value));
|
projections
|
||||||
|
.add(new FieldProjection(field, value, value instanceof Integer ? ProjectOn.PATH : ProjectOn.NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
return projections;
|
return projections;
|
||||||
@@ -1382,12 +1433,13 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
|||||||
* @return {@literal true} if this field is excluded.
|
* @return {@literal true} if this field is excluded.
|
||||||
*/
|
*/
|
||||||
public boolean isExcluded() {
|
public boolean isExcluded() {
|
||||||
return Boolean.FALSE.equals(value);
|
return Boolean.FALSE.equals(value) || value instanceof Number number && number.intValue() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Document toDocument(AggregationOperationContext context) {
|
public Document toDocument(AggregationOperationContext context) {
|
||||||
return new Document(field.getName(), renderFieldValue(context));
|
return new Document(ProjectOn.NAME.equals(projectOn) ? field.getName() : context.getReference(field.getTarget()).getRaw(),
|
||||||
|
renderFieldValue(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object renderFieldValue(AggregationOperationContext context) {
|
private Object renderFieldValue(AggregationOperationContext context) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.springframework.data.mongodb.core.aggregation.ProjectionOperationUnit
|
|||||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Field;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
|
|
||||||
@@ -653,6 +654,58 @@ public class AggregationUnitTests {
|
|||||||
assertThat(documents.get(2)).isEqualTo("{ $sort : { 'serial_number' : -1, 'label_name' : -1 } }");
|
assertThat(documents.get(2)).isEqualTo("{ $sort : { 'serial_number' : -1, 'label_name' : -1 } }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // GH-4428
|
||||||
|
void projectIncludePath() {
|
||||||
|
|
||||||
|
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||||
|
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(
|
||||||
|
Root.class, mappingContext,
|
||||||
|
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
|
||||||
|
|
||||||
|
assertThat(project("flat").andIncludePath("list.element").toDocument(context)).isEqualTo(
|
||||||
|
Document.parse("""
|
||||||
|
{
|
||||||
|
"$project": {
|
||||||
|
"flat": 1,
|
||||||
|
"list.elE_m_enT": 1
|
||||||
|
}
|
||||||
|
}""")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // GH-4428
|
||||||
|
void projectExcludePath() {
|
||||||
|
|
||||||
|
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||||
|
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(
|
||||||
|
Root.class, mappingContext,
|
||||||
|
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
|
||||||
|
|
||||||
|
assertThat(project("flat").andExcludePath("list.element").toDocument(context)).isEqualTo(
|
||||||
|
Document.parse("""
|
||||||
|
{
|
||||||
|
"$project": {
|
||||||
|
"flat": 1,
|
||||||
|
"list.elE_m_enT": 0
|
||||||
|
}
|
||||||
|
}""")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Root {
|
||||||
|
String flat;
|
||||||
|
List<Nested> list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Nested {
|
||||||
|
|
||||||
|
@Field("elE_m_enT")
|
||||||
|
int element;
|
||||||
|
String description;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private Document extractPipelineElement(Document agg, int index, String operation) {
|
private Document extractPipelineElement(Document agg, int index, String operation) {
|
||||||
|
|
||||||
List<Document> pipeline = (List<Document>) agg.get("pipeline");
|
List<Document> pipeline = (List<Document>) agg.get("pipeline");
|
||||||
|
|||||||
Reference in New Issue
Block a user