Skip to content

Commit 96d59ac

Browse files
Gaffmsmercjyemin
authored
Add $set method to Aggregates (#574)
JAVA-3835 Co-authored-by: mshaylor <[email protected]> Co-authored-by: Jeff Yemin <[email protected]>
1 parent 412f8b8 commit 96d59ac

File tree

6 files changed

+85
-12
lines changed

6 files changed

+85
-12
lines changed

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

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,38 @@ public static Bson addFields(final Field<?>... fields) {
6464
* @since 3.4
6565
*/
6666
public static Bson addFields(final List<Field<?>> fields) {
67-
return new AddFieldsStage(fields);
67+
return new FieldsStage("$addFields", fields);
6868
}
6969

70+
/**
71+
* Creates a $set pipeline stage for the specified projection
72+
*
73+
* @param fields the fields to add
74+
* @return the $set pipeline stage
75+
* @see Projections
76+
* @since 4.3
77+
* @mongodb.server.release 4.2
78+
* @mongodb.driver.manual reference/operator/aggregation/set/ $set
79+
*/
80+
public static Bson set(final Field<?>... fields) {
81+
return set(asList(fields));
82+
}
83+
84+
/**
85+
* Creates a $set pipeline stage for the specified projection
86+
*
87+
* @param fields the fields to add
88+
* @return the $set pipeline stage
89+
* @see Projections
90+
* @since 4.3
91+
* @mongodb.server.release 4.2
92+
* @mongodb.driver.manual reference/operator/aggregation/set/ $set
93+
*/
94+
public static Bson set(final List<Field<?>> fields) {
95+
return new FieldsStage("$set", fields);
96+
}
97+
98+
7099
/**
71100
* Creates a $bucket pipeline stage
72101
*
@@ -1148,18 +1177,20 @@ public String toString() {
11481177

11491178
}
11501179

1151-
private static class AddFieldsStage implements Bson {
1180+
private static class FieldsStage implements Bson {
11521181
private final List<Field<?>> fields;
1182+
private final String stageName; //one of $addFields or $set
11531183

1154-
AddFieldsStage(final List<Field<?>> fields) {
1155-
this.fields = fields;
1184+
FieldsStage(final String stageName, final List<Field<?>> fields) {
1185+
this.stageName = stageName;
1186+
this.fields = notNull("fields", fields);
11561187
}
11571188

11581189
@Override
11591190
public <TDocument> BsonDocument toBsonDocument(final Class<TDocument> tDocumentClass, final CodecRegistry codecRegistry) {
11601191
BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument());
11611192
writer.writeStartDocument();
1162-
writer.writeName("$addFields");
1193+
writer.writeName(stageName);
11631194
writer.writeStartDocument();
11641195
for (Field<?> field : fields) {
11651196
writer.writeName(field.getName());
@@ -1180,20 +1211,25 @@ public boolean equals(final Object o) {
11801211
return false;
11811212
}
11821213

1183-
AddFieldsStage that = (AddFieldsStage) o;
1214+
FieldsStage that = (FieldsStage) o;
11841215

1185-
return fields != null ? fields.equals(that.fields) : that.fields == null;
1216+
if (!fields.equals(that.fields)) {
1217+
return false;
1218+
}
1219+
return stageName.equals(that.stageName);
11861220
}
11871221

11881222
@Override
11891223
public int hashCode() {
1190-
return fields != null ? fields.hashCode() : 0;
1224+
int result = fields.hashCode();
1225+
result = 31 * result + stageName.hashCode();
1226+
return result;
11911227
}
11921228

11931229
@Override
11941230
public String toString() {
11951231
return "Stage{"
1196-
+ "name='$addFields', "
1232+
+ "name='" + stageName + "', "
11971233
+ "fields=" + fields
11981234
+ '}';
11991235
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import static com.mongodb.client.model.Aggregates.project
5353
import static com.mongodb.client.model.Aggregates.replaceRoot
5454
import static com.mongodb.client.model.Aggregates.replaceWith
5555
import static com.mongodb.client.model.Aggregates.sample
56+
import static com.mongodb.client.model.Aggregates.set
5657
import static com.mongodb.client.model.Aggregates.skip
5758
import static com.mongodb.client.model.Aggregates.sort
5859
import static com.mongodb.client.model.Aggregates.sortByCount
@@ -921,6 +922,14 @@ class AggregatesFunctionalSpecification extends OperationFunctionalSpecification
921922
helper?.drop()
922923
}
923924

925+
@IgnoreIf({ !serverVersionAtLeast(4, 2) })
926+
def '$set'() {
927+
expect:
928+
aggregate([set(new Field('c', '$y'))]) == [new Document(a).append('c', 'a'),
929+
new Document(b).append('c', 'b'),
930+
new Document(c).append('c', 'c')]
931+
}
932+
924933
@IgnoreIf({ !serverVersionAtLeast(3, 4) })
925934
def '$replaceRoot'() {
926935
given:

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import static com.mongodb.client.model.Aggregates.project
5353
import static com.mongodb.client.model.Aggregates.replaceRoot
5454
import static com.mongodb.client.model.Aggregates.replaceWith
5555
import static com.mongodb.client.model.Aggregates.sample
56+
import static com.mongodb.client.model.Aggregates.set
5657
import static com.mongodb.client.model.Aggregates.skip
5758
import static com.mongodb.client.model.Aggregates.sort
5859
import static com.mongodb.client.model.Aggregates.sortByCount
@@ -106,7 +107,6 @@ class AggregatesSpecification extends Specification {
106107
'", finalize: "' + finalizeFunction + '", lang: "js"}}}}')
107108
}
108109

109-
@IgnoreIf({ !serverVersionAtLeast(3, 4) })
110110
def 'should render $addFields'() {
111111
expect:
112112
toBson(addFields(new Field('newField', null))) == parse('{$addFields: {newField: null}}')
@@ -120,6 +120,19 @@ class AggregatesSpecification extends Specification {
120120
toBson(addFields(asList(new Field('b', 3), new Field('c', 5)))) == parse('{$addFields: {b: 3, c: 5}}')
121121
}
122122

123+
def 'should render $set'() {
124+
expect:
125+
toBson(set(new Field('newField', null))) == parse('{$set: {newField: null}}')
126+
toBson(set(new Field('newField', 'hello'))) == parse('{$set: {newField: "hello"}}')
127+
toBson(set(new Field('this', '$$CURRENT'))) == parse('{$set: {this: "$$CURRENT"}}')
128+
toBson(set(new Field('myNewField', new Document('c', 3)
129+
.append('d', 4)))) == parse('{$set: {myNewField: {c: 3, d: 4}}}')
130+
toBson(set(new Field('alt3', new Document('$lt', asList('$a', 3))))) == parse(
131+
'{$set: {alt3: {$lt: ["$a", 3]}}}')
132+
toBson(set(new Field('b', 3), new Field('c', 5))) == parse('{$set: {b: 3, c: 5}}')
133+
toBson(set(asList(new Field('b', 3), new Field('c', 5)))) == parse('{$set: {b: 3, c: 5}}')
134+
}
135+
123136
def 'should render $bucket'() {
124137
expect:
125138
toBson(bucket('$screenSize', [0, 24, 32, 50, 100000])) == parse('''{

driver-scala/src/it/scala/tour/QuickTour.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import org.mongodb.scala.model.Aggregates._
4141
import org.mongodb.scala.model.Filters._
4242
import org.mongodb.scala.model.Projections._
4343
import org.mongodb.scala.model.Sorts._
44-
import org.mongodb.scala.model.Updates._
44+
import org.mongodb.scala.model.Updates.{ inc, set }
4545
import org.mongodb.scala.model.changestream.ChangeStreamDocument
4646
import tour.Helpers._
4747

driver-scala/src/main/scala/org/mongodb/scala/model/Aggregates.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,18 @@ object Aggregates {
4242
def addFields(fields: Field[_]*): Bson = JAggregates.addFields(fields.asJava)
4343

4444
/**
45-
* Creates a `\$bucket` pipeline stage
45+
* Creates an \$set pipeline stage
46+
*
47+
* @param fields the fields to add
48+
* @return the \$set pipeline stage
49+
* @see [[http://docs.mongodb.org/manual/reference/operator/aggregation/set/ \$set]]
50+
* @since 4.3
51+
* @note Requires MongoDB 4.2 or greater
52+
*/
53+
def set(fields: Field[_]*): Bson = JAggregates.set(fields.asJava)
54+
55+
/**
56+
* Creates a \$bucket pipeline stage
4657
*
4758
* @param groupBy the criteria to group By
4859
* @param boundaries the boundaries of the buckets

driver-scala/src/test/scala/org/mongodb/scala/model/AggregatesSpec.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class AggregatesSpec extends BaseSpec {
6060
toBson(addFields(Field("newField", "hello"))) should equal(Document("""{$addFields: { "newField": "hello"}}"""))
6161
}
6262

63+
it should "render $set" in {
64+
toBson(set(Field("newField", "hello"))) should equal(Document("""{$set: { "newField": "hello"}}"""))
65+
}
66+
6367
// scalastyle:off magic.number
6468
it should "render $bucket" in {
6569
toBson(bucket("$screenSize", 0, 24, 32, 50, 100000)) should equal(

0 commit comments

Comments
 (0)