Skip to content

Commit 402c968

Browse files
committed
Added Aggregates.replaceWith helper
JAVA-3305
1 parent aa83265 commit 402c968

File tree

3 files changed

+80
-10
lines changed

3 files changed

+80
-10
lines changed

driver-core/src/main/com/mongodb/client/model/Aggregates.java

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,26 @@ public static Bson merge(final MongoNamespace namespace, final MergeOptions opti
490490
* @since 3.4
491491
*/
492492
public static <TExpression> Bson replaceRoot(final TExpression value) {
493-
return new ReplaceRootStage<TExpression>(value);
493+
return new ReplaceStage<TExpression>(value);
494+
}
495+
496+
/**
497+
* Creates a $replaceRoot pipeline stage
498+
*
499+
* <p>With $replaceWith, you can promote an embedded document to the top-level.
500+
* You can also specify a new document as the replacement.</p>
501+
*
502+
* <p>The $replaceWith is an alias for {@link #replaceRoot(Object)}.</p>
503+
*
504+
* @param <TExpression> the new root type
505+
* @param value the new root value
506+
* @return the $replaceRoot pipeline stage
507+
* @mongodb.driver.manual reference/operator/aggregation/replaceWith/ $replaceWith
508+
* @mongodb.server.release 4.2
509+
* @since 3.11
510+
*/
511+
public static <TExpression> Bson replaceWith(final TExpression value) {
512+
return new ReplaceStage<TExpression>(value, true);
494513
}
495514

496515
/**
@@ -1140,22 +1159,34 @@ public String toString() {
11401159
}
11411160
}
11421161

1143-
private static class ReplaceRootStage<TExpression> implements Bson {
1162+
private static class ReplaceStage<TExpression> implements Bson {
11441163
private final TExpression value;
1164+
private final boolean replaceWith;
1165+
1166+
ReplaceStage(final TExpression value) {
1167+
this(value, false);
1168+
}
11451169

1146-
ReplaceRootStage(final TExpression value) {
1170+
ReplaceStage(final TExpression value, final boolean replaceWith) {
11471171
this.value = value;
1172+
this.replaceWith = replaceWith;
11481173
}
11491174

11501175
@Override
11511176
public <TDocument> BsonDocument toBsonDocument(final Class<TDocument> tDocumentClass, final CodecRegistry codecRegistry) {
11521177
BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument());
11531178
writer.writeStartDocument();
1154-
writer.writeName("$replaceRoot");
1155-
writer.writeStartDocument();
1156-
writer.writeName("newRoot");
1157-
BuildersHelper.encodeValue(writer, value, codecRegistry);
1158-
writer.writeEndDocument();
1179+
1180+
if (replaceWith) {
1181+
writer.writeName("$replaceWith");
1182+
BuildersHelper.encodeValue(writer, value, codecRegistry);
1183+
} else {
1184+
writer.writeName("$replaceRoot");
1185+
writer.writeStartDocument();
1186+
writer.writeName("newRoot");
1187+
BuildersHelper.encodeValue(writer, value, codecRegistry);
1188+
writer.writeEndDocument();
1189+
}
11591190
writer.writeEndDocument();
11601191

11611192
return writer.getDocument();
@@ -1170,7 +1201,7 @@ public boolean equals(final Object o) {
11701201
return false;
11711202
}
11721203

1173-
ReplaceRootStage<?> that = (ReplaceRootStage<?>) o;
1204+
ReplaceStage<?> that = (ReplaceStage<?>) o;
11741205

11751206
return value != null ? value.equals(that.value) : that.value == null;
11761207
}

driver-core/src/test/functional/com/mongodb/client/model/AggregatesFunctionalSpecification.groovy

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import static com.mongodb.client.model.Aggregates.merge
5050
import static com.mongodb.client.model.Aggregates.out
5151
import static com.mongodb.client.model.Aggregates.project
5252
import static com.mongodb.client.model.Aggregates.replaceRoot
53+
import static com.mongodb.client.model.Aggregates.replaceWith
5354
import static com.mongodb.client.model.Aggregates.sample
5455
import static com.mongodb.client.model.Aggregates.skip
5556
import static com.mongodb.client.model.Aggregates.sort
@@ -890,4 +891,35 @@ class AggregatesFunctionalSpecification extends OperationFunctionalSpecification
890891
then:
891892
results == [Document.parse('{b: 1, _id: 7}')]
892893
}
894+
895+
@IgnoreIf({ !serverVersionAtLeast(4, 2) })
896+
def '$replaceWith'() {
897+
given:
898+
def helper = getCollectionHelper()
899+
def results = []
900+
901+
when:
902+
helper.drop()
903+
helper.insertDocuments(Document.parse('{_id: 0, a1: {b: 1}, a2: 2}'))
904+
results = helper.aggregate([replaceWith('$a1')])
905+
906+
then:
907+
results == [Document.parse('{b: 1}')]
908+
909+
when:
910+
helper.drop()
911+
helper.insertDocuments(Document.parse('{_id: 0, a1: {b: {c1: 4, c2: 5}}, a2: 2}'))
912+
results = helper.aggregate([replaceWith('$a1.b')])
913+
914+
then:
915+
results == [Document.parse('{c1: 4, c2: 5}')]
916+
917+
when:
918+
helper.drop()
919+
helper.insertDocuments(Document.parse('{_id: 0, a1: {b: 1, _id: 7}, a2: 2}'))
920+
results = helper.aggregate([replaceWith('$a1')])
921+
922+
then:
923+
results == [Document.parse('{b: 1, _id: 7}')]
924+
}
893925
}

driver-core/src/test/unit/com/mongodb/client/model/AggregatesSpecification.groovy

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import static com.mongodb.client.model.Aggregates.merge
5050
import static com.mongodb.client.model.Aggregates.out
5151
import static com.mongodb.client.model.Aggregates.project
5252
import static com.mongodb.client.model.Aggregates.replaceRoot
53+
import static com.mongodb.client.model.Aggregates.replaceWith
5354
import static com.mongodb.client.model.Aggregates.sample
5455
import static com.mongodb.client.model.Aggregates.skip
5556
import static com.mongodb.client.model.Aggregates.sort
@@ -169,14 +170,20 @@ class AggregatesSpecification extends Specification {
169170
parse('{ $project : { title : 1 , author : 1, lastName : "$author.last" } }')
170171
}
171172

172-
@IgnoreIf({ !serverVersionAtLeast(3, 4) })
173173
def 'should render $replaceRoot'() {
174174
expect:
175175
toBson(replaceRoot('$a1')) == parse('{$replaceRoot: {newRoot: "$a1"}}')
176176
toBson(replaceRoot('$a1.b')) == parse('{$replaceRoot: {newRoot: "$a1.b"}}')
177177
toBson(replaceRoot('$a1')) == parse('{$replaceRoot: {newRoot: "$a1"}}')
178178
}
179179

180+
def 'should render $replaceWith'() {
181+
expect:
182+
toBson(replaceWith('$a1')) == parse('{$replaceWith: "$a1"}')
183+
toBson(replaceWith('$a1.b')) == parse('{$replaceWith: "$a1.b"}')
184+
toBson(replaceWith('$a1')) == parse('{$replaceWith: "$a1"}')
185+
}
186+
180187
def 'should render $sort'() {
181188
expect:
182189
toBson(sort(ascending('title', 'author'))) == parse('{ $sort : { title : 1 , author : 1 } }')

0 commit comments

Comments
 (0)