Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20a8b5e5f1 | ||
|
|
3c25ed8378 | ||
|
|
6c21eab84b | ||
|
|
f00e8ed93c | ||
|
|
34a35bd489 | ||
|
|
ba2b65cfd5 | ||
|
|
2c9975e8db | ||
|
|
781ba63226 |
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.7</version>
|
||||
<version>3.2.8</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -26,7 +26,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>2.5.7</springdata.commons>
|
||||
<springdata.commons>2.5.8</springdata.commons>
|
||||
<mongo>4.2.3</mongo>
|
||||
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.7</version>
|
||||
<version>3.2.8</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.7</version>
|
||||
<version>3.2.8</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.7</version>
|
||||
<version>3.2.8</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -1803,8 +1803,9 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
||||
Document projections = new Document();
|
||||
|
||||
Fields fields = context.getFields(type);
|
||||
fields.forEach(it -> projections.append(it.getName(), 1));
|
||||
return context.getMappedObject(projections, type);
|
||||
|
||||
fields.forEach(it -> projections.append(it.getTarget(), 1));
|
||||
return projections;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference;
|
||||
@@ -122,13 +122,13 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
return AggregationOperationContext.super.getFields(type);
|
||||
}
|
||||
|
||||
List<String> fields = new ArrayList<>();
|
||||
List<Field> fields = new ArrayList<>();
|
||||
|
||||
for (MongoPersistentProperty property : entity) {
|
||||
fields.add(property.getName());
|
||||
fields.add(Fields.field(property.getName(), property.getFieldName()));
|
||||
}
|
||||
|
||||
return Fields.fields(fields.toArray(new String[0]));
|
||||
return Fields.from(fields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,12 +142,13 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
|
||||
/**
|
||||
* This toggle allows the {@link AggregationOperationContext context} to use any given field name without checking for
|
||||
* its existence. Typically the {@link AggregationOperationContext} fails when referencing unknown fields, those that
|
||||
* its existence. Typically, the {@link AggregationOperationContext} fails when referencing unknown fields, those that
|
||||
* are not present in one of the previous stages or the input source, throughout the pipeline.
|
||||
*
|
||||
* @param type The domain type to map fields to.
|
||||
* @return a more relaxed {@link AggregationOperationContext}.
|
||||
* @since 3.1
|
||||
* @see RelaxedTypeBasedAggregationOperationContext
|
||||
*/
|
||||
public AggregationOperationContext continueOnMissingFieldReference(Class<?> type) {
|
||||
return new RelaxedTypeBasedAggregationOperationContext(type, mappingContext, mapper);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2021 the original author or authors.
|
||||
* Copyright 2011-2022 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.
|
||||
@@ -1388,6 +1388,14 @@ public class QueryMapper {
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
|
||||
String nextToken() {
|
||||
return pathParts.get(currentIndex + 1);
|
||||
}
|
||||
|
||||
boolean hasNexToken() {
|
||||
return pathParts.size() > currentIndex + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the property name while retaining potential positional operator {@literal $}.
|
||||
*
|
||||
@@ -1397,31 +1405,26 @@ public class QueryMapper {
|
||||
protected String mapPropertyName(MongoPersistentProperty property) {
|
||||
|
||||
StringBuilder mappedName = new StringBuilder(PropertyToFieldNameConverter.INSTANCE.convert(property));
|
||||
|
||||
boolean inspect = iterator.hasNext();
|
||||
|
||||
while (inspect) {
|
||||
|
||||
String partial = iterator.next();
|
||||
currentIndex++;
|
||||
|
||||
boolean isPositional = isPositionalParameter(partial) && property.isCollectionLike() ;
|
||||
if(property.isMap() && currentPropertyRoot.equals(partial) && iterator.hasNext()){
|
||||
partial = iterator.next();
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
if (isPositional || property.isMap() && !currentPropertyRoot.equals(partial)) {
|
||||
mappedName.append(".").append(partial);
|
||||
}
|
||||
|
||||
inspect = isPositional && iterator.hasNext();
|
||||
if (!hasNexToken()) {
|
||||
return mappedName.toString();
|
||||
}
|
||||
|
||||
if(currentIndex + 1 < pathParts.size()) {
|
||||
currentIndex++;
|
||||
currentPropertyRoot = pathParts.get(currentIndex);
|
||||
String nextToken = nextToken();
|
||||
if (isPositionalParameter(nextToken)) {
|
||||
|
||||
mappedName.append(".").append(nextToken);
|
||||
currentIndex += 2;
|
||||
return mappedName.toString();
|
||||
}
|
||||
|
||||
if (property.isMap()) {
|
||||
|
||||
mappedName.append(".").append(nextToken);
|
||||
currentIndex += 2;
|
||||
return mappedName.toString();
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
return mappedName.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond;
|
||||
import org.springframework.data.mongodb.core.aggregation.ProjectionOperationUnitTests.BookWithFieldAnnotation;
|
||||
@@ -598,9 +599,31 @@ public class AggregationUnitTests {
|
||||
assertThat(extractPipelineElement(target, 1, "$project")).isEqualTo(Document.parse(" { \"_id\" : \"$_id\" }"));
|
||||
}
|
||||
|
||||
|
||||
@Test // GH-3898
|
||||
void shouldNotConvertIncludeExcludeValuesForProjectOperation() {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
RelaxedTypeBasedAggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(WithRetypedIdField.class, mappingContext,
|
||||
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext)));
|
||||
Document document = project(WithRetypedIdField.class).toDocument(context);
|
||||
assertThat(document).isEqualTo(new Document("$project", new Document("_id", 1).append("renamed-field", 1)));
|
||||
}
|
||||
|
||||
private Document extractPipelineElement(Document agg, int index, String operation) {
|
||||
|
||||
List<Document> pipeline = (List<Document>) agg.get("pipeline");
|
||||
return (Document) pipeline.get(index).get(operation);
|
||||
}
|
||||
|
||||
public class WithRetypedIdField {
|
||||
|
||||
@Id
|
||||
@org.springframework.data.mongodb.core.mapping.Field
|
||||
private String id;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field("renamed-field")
|
||||
private String foo;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2021 the original author or authors.
|
||||
* Copyright 2013-2022 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.
|
||||
@@ -1208,7 +1208,7 @@ class UpdateMapperUnitTests {
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(EntityWithNestedMap.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("levelOne.a.b.d","e")));
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set", new org.bson.Document("levelOne.a.b.d", "e")));
|
||||
}
|
||||
|
||||
@Test // GH-3775
|
||||
@@ -1218,7 +1218,7 @@ class UpdateMapperUnitTests {
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(EntityWithNestedMap.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("levelOne.0.1.3","4")));
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set", new org.bson.Document("levelOne.0.1.3", "4")));
|
||||
}
|
||||
|
||||
@Test // GH-3775
|
||||
@@ -1228,7 +1228,7 @@ class UpdateMapperUnitTests {
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(EntityWithNestedMap.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("levelOne.0.1.c","4")));
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set", new org.bson.Document("levelOne.0.1.c", "4")));
|
||||
}
|
||||
|
||||
@Test // GH-3775
|
||||
@@ -1238,7 +1238,7 @@ class UpdateMapperUnitTests {
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(EntityWithNestedMap.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("levelOne.0a.1b.3c","4")));
|
||||
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set", new org.bson.Document("levelOne.0a.1b.3c", "4")));
|
||||
}
|
||||
|
||||
@Test // GH-3688
|
||||
@@ -1251,6 +1251,36 @@ class UpdateMapperUnitTests {
|
||||
assertThat(mappedUpdate).isEqualTo("{\"$set\": {\"intKeyedMap.1a.map.0b\": \"testing\"}}");
|
||||
}
|
||||
|
||||
@Test // GH-3921
|
||||
void mapNumericKeyInPathHavingComplexMapValyeTypes() {
|
||||
|
||||
Update update = new Update().set("testInnerData.testMap.1.intValue", "4");
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(TestData.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo("{ $set: { 'testInnerData.testMap.1.intValue': '4' }}");
|
||||
}
|
||||
|
||||
@Test // GH-3921
|
||||
void mapNumericKeyInPathNotMatchingExistingProperties() {
|
||||
|
||||
Update update = new Update().set("testInnerData.imaginaryMap.1.nonExistingProperty", "4");
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(TestData.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo("{ $set: { 'testInnerData.imaginaryMap.1.nonExistingProperty': '4' }}");
|
||||
}
|
||||
|
||||
@Test // GH-3921
|
||||
void mapNumericKeyInPathPartiallyMatchingExistingProperties() {
|
||||
|
||||
Update update = new Update().set("testInnerData.testMap.1.nonExistingProperty.2.someValue", "4");
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(TestData.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo("{ $set: { 'testInnerData.testMap.1.nonExistingProperty.2.someValue': '4' }}");
|
||||
}
|
||||
|
||||
static class DomainTypeWrappingConcreteyTypeHavingListOfInterfaceTypeAttributes {
|
||||
ListModelWrapper concreteTypeWithListAttributeOfInterfaceType;
|
||||
}
|
||||
@@ -1487,7 +1517,7 @@ class UpdateMapperUnitTests {
|
||||
Map<Object, NestedDocument> concreteMap;
|
||||
}
|
||||
|
||||
static class EntityWithIntKeyedMap{
|
||||
static class EntityWithIntKeyedMap {
|
||||
Map<Integer, EntityWithObjectMap> intKeyedMap;
|
||||
}
|
||||
|
||||
@@ -1621,4 +1651,19 @@ class UpdateMapperUnitTests {
|
||||
Map<String, Map<String, Map<String, Object>>> levelOne;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class TestData {
|
||||
@Id private String id;
|
||||
private TestInnerData testInnerData;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class TestInnerData {
|
||||
private Map<Integer, TestValue> testMap;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class TestValue {
|
||||
private int intValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 3.2.7 (2021.0.7)
|
||||
Spring Data MongoDB 3.2.8 (2021.0.8)
|
||||
Copyright (c) [2010-2019] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
@@ -32,5 +32,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user