1717
1818import org .bson .Document ;
1919import org .jspecify .annotations .Nullable ;
20- import org . springframework . data . mongodb . util . BsonUtils ;
20+
2121import org .springframework .lang .Contract ;
2222import org .springframework .util .Assert ;
2323import org .springframework .util .StringUtils ;
@@ -37,33 +37,25 @@ public class OutOperation implements AggregationOperation {
3737
3838 private final @ Nullable String databaseName ;
3939 private final String collectionName ;
40- private final @ Nullable Document uniqueKey ;
41- private final @ Nullable OutMode mode ;
4240
4341 /**
4442 * @param outCollectionName Collection name to export the results. Must not be {@literal null}.
4543 */
4644 public OutOperation (String outCollectionName ) {
47- this (null , outCollectionName , null , null );
45+ this (null , outCollectionName );
4846 }
4947
5048 /**
5149 * @param databaseName Optional database name the target collection is located in. Can be {@literal null}.
5250 * @param collectionName Collection name to export the results. Must not be {@literal null}. Can be {@literal null}.
53- * @param uniqueKey Optional unique key spec identify a document in the to collection for replacement or merge.
54- * @param mode The mode for merging the aggregation pipeline output with the target collection. Can be
55- * {@literal null}. {@literal null}.
5651 * @since 2.2
5752 */
58- private OutOperation (@ Nullable String databaseName , String collectionName , @ Nullable Document uniqueKey ,
59- @ Nullable OutMode mode ) {
53+ private OutOperation (@ Nullable String databaseName , String collectionName ) {
6054
6155 Assert .notNull (collectionName , "Collection name must not be null" );
6256
6357 this .databaseName = databaseName ;
6458 this .collectionName = collectionName ;
65- this .uniqueKey = uniqueKey ;
66- this .mode = mode ;
6759 }
6860
6961 /**
@@ -76,187 +68,21 @@ private OutOperation(@Nullable String databaseName, String collectionName, @Null
7668 */
7769 @ Contract ("_ -> new" )
7870 public OutOperation in (@ Nullable String database ) {
79- return new OutOperation (database , collectionName , uniqueKey , mode );
80- }
81-
82- /**
83- * Optionally specify the field that uniquely identifies a document in the target collection. <br />
84- * For convenience the given {@literal key} can either be a single field name or the Json representation of a key
85- * {@link Document}.
86- *
87- * <pre class="code">
88- *
89- * // {
90- * // "field-1" : 1
91- * // }
92- * .uniqueKey("field-1")
93- *
94- * // {
95- * // "field-1" : 1,
96- * // "field-2" : 1
97- * // }
98- * .uniqueKey("{ 'field-1' : 1, 'field-2' : 1}")
99- * </pre>
100- *
101- * <strong>NOTE:</strong> Requires MongoDB 4.2 or later.
102- *
103- * @param key can be {@literal null}. Server uses {@literal _id} when {@literal null}.
104- * @return new instance of {@link OutOperation}.
105- * @since 2.2
106- */
107- @ Contract ("_ -> new" )
108- public OutOperation uniqueKey (@ Nullable String key ) {
109-
110- Document uniqueKey = key == null ? null : BsonUtils .toDocumentOrElse (key , it -> new Document (it , 1 ));
111- return new OutOperation (databaseName , collectionName , uniqueKey , mode );
112- }
113-
114- /**
115- * Optionally specify the fields that uniquely identifies a document in the target collection. <br />
116- *
117- * <pre class="code">
118- *
119- * // {
120- * // "field-1" : 1
121- * // "field-2" : 1
122- * // }
123- * .uniqueKeyOf(Arrays.asList("field-1", "field-2"))
124- * </pre>
125- *
126- * <strong>NOTE:</strong> Requires MongoDB 4.2 or later.
127- *
128- * @param fields must not be {@literal null}.
129- * @return new instance of {@link OutOperation}.
130- * @since 2.2
131- */
132- @ Contract ("_ -> new" )
133- public OutOperation uniqueKeyOf (Iterable <String > fields ) {
134-
135- Assert .notNull (fields , "Fields must not be null" );
136-
137- Document uniqueKey = new Document ();
138- fields .forEach (it -> uniqueKey .append (it , 1 ));
139-
140- return new OutOperation (databaseName , collectionName , uniqueKey , mode );
141- }
142-
143- /**
144- * Specify how to merge the aggregation output with the target collection. <br />
145- * <strong>NOTE:</strong> Requires MongoDB 4.2 or later.
146- *
147- * @param mode must not be {@literal null}.
148- * @return new instance of {@link OutOperation}.
149- * @since 2.2
150- */
151- @ Contract ("_ -> new" )
152- public OutOperation mode (OutMode mode ) {
153-
154- Assert .notNull (mode , "Mode must not be null" );
155- return new OutOperation (databaseName , collectionName , uniqueKey , mode );
156- }
157-
158- /**
159- * Replace the target collection. <br />
160- * <strong>NOTE:</strong> Requires MongoDB 4.2 or later.
161- *
162- * @return new instance of {@link OutOperation}.
163- * @see OutMode#REPLACE_COLLECTION
164- * @since 2.2
165- */
166- @ Contract ("-> new" )
167- public OutOperation replaceCollection () {
168- return mode (OutMode .REPLACE_COLLECTION );
169- }
170-
171- /**
172- * Replace/Upsert documents in the target collection. <br />
173- * <strong>NOTE:</strong> Requires MongoDB 4.2 or later.
174- *
175- * @return new instance of {@link OutOperation}.
176- * @see OutMode#REPLACE
177- * @since 2.2
178- */
179- @ Contract ("-> new" )
180- public OutOperation replaceDocuments () {
181- return mode (OutMode .REPLACE );
182- }
183-
184- /**
185- * Insert documents to the target collection. <br />
186- * <strong>NOTE:</strong> Requires MongoDB 4.2 or later.
187- *
188- * @return new instance of {@link OutOperation}.
189- * @see OutMode#INSERT
190- * @since 2.2
191- */
192- @ Contract ("-> new" )
193- public OutOperation insertDocuments () {
194- return mode (OutMode .INSERT );
71+ return new OutOperation (database , collectionName );
19572 }
19673
19774 @ Override
19875 public Document toDocument (AggregationOperationContext context ) {
19976
200- if (!requiresMongoDb42Format ( )) {
201- return new Document ("$out" , collectionName );
77+ if (!StringUtils . hasText ( databaseName )) {
78+ return new Document (getOperator () , collectionName );
20279 }
20380
204- Assert .state (mode != null , "Mode must not be null" );
205-
206- Document $out = new Document ("to" , collectionName ) //
207- .append ("mode" , mode .getMongoMode ());
208-
209- if (StringUtils .hasText (databaseName )) {
210- $out .append ("db" , databaseName );
211- }
212-
213- if (uniqueKey != null ) {
214- $out .append ("uniqueKey" , uniqueKey );
215- }
216-
217- return new Document (getOperator (), $out );
81+ return new Document (getOperator (), new Document ("db" , databaseName ).append ("coll" , collectionName ));
21882 }
21983
22084 @ Override
22185 public String getOperator () {
22286 return "$out" ;
22387 }
224-
225- private boolean requiresMongoDb42Format () {
226- return StringUtils .hasText (databaseName ) || mode != null || uniqueKey != null ;
227- }
228-
229- /**
230- * The mode for merging the aggregation pipeline output.
231- *
232- * @author Christoph Strobl
233- * @since 2.2
234- */
235- public enum OutMode {
236-
237- /**
238- * Write documents to the target collection. Errors if a document same uniqueKey already exists.
239- */
240- INSERT ("insertDocuments" ),
241-
242- /**
243- * Update on any document in the target collection with the same uniqueKey.
244- */
245- REPLACE ("replaceDocuments" ),
246-
247- /**
248- * Replaces the to collection with the output from the aggregation pipeline. Cannot be in a different database.
249- */
250- REPLACE_COLLECTION ("replaceCollection" );
251-
252- private final String mode ;
253-
254- OutMode (String mode ) {
255- this .mode = mode ;
256- }
257-
258- public String getMongoMode () {
259- return mode ;
260- }
261- }
26288}
0 commit comments