You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/90-exporting-data/saving-to-collection.mdx
+205-5
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,9 @@ import TabItem from '@theme/TabItem';
3
3
4
4
# 🦸 Saving to a Collection
5
5
6
-
You can export the result of an aggregation pipeline to a different DB/collection. To do that, just add a last aggregation stage to your pipeline:
6
+
# $out
7
+
8
+
You can export the result of an aggregation pipeline to a different DB/collection. To do that, just add a last aggregation stage `$out` to your pipeline:
7
9
8
10
<TabsgroupId="aggregations">
9
11
<TabItemvalue="atlas"label="Atlas UI">
@@ -33,6 +35,11 @@ You can omit the `db` attribute, and the new collection will be created in the c
33
35
{ $out:"<output-collection>" }
34
36
```
35
37
38
+
:::info
39
+
The `$out` stage must be the last stage in the pipeline.
40
+
:::
41
+
42
+
36
43
👐 Create a copy of the books with exactly 100 pages and output as a new collection named `OneHundredPagesBooks`.
37
44
38
45
<details>
@@ -49,6 +56,8 @@ You can omit the `db` attribute, and the new collection will be created in the c
If the collection specified by the `$out` operation already exists, then the `$out` stage atomically replaces the existing collection with the new results collection upon completion of the aggregation.
95
+
96
+
To avoid overwriting the existing collection we can use `$merge` instead of `$out`.
97
+
98
+
```
99
+
{ $merge : { into : "newCollection" } }
100
+
```
101
+
102
+
- if the collection does not exists, it will be created
103
+
- if it exists, new data will be added
104
+
- if [a doc already exists](https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#std-label-merge-whenMatched), we can replace it, keep the existing one, merge both documents cause the stage to fail or run a pipeline.
105
+
106
+
This is perfect for creating [On-Demand Materialized Views](https://www.mongodb.com/docs/manual/core/materialized-views/)
107
+
108
+
As an example, let's say we want the authors to contain all the books they've written, with all the book information. In this case, we'll do a `$lookup` to get the book information into the authors collection. We can even use the name `books` for the resulting data we're joining, shadowing the original `books` array we have in authors. This way it will look like the `books` array changes.
72
109
73
110
```js
74
-
show collections
111
+
[
112
+
{$lookup: {
113
+
from:"books",
114
+
localField:"books",
115
+
foreignField:"_id",
116
+
as:"books"
117
+
}
118
+
},
119
+
]
75
120
```
76
-
</div>
77
-
</details>
121
+
122
+
Now a book will look like this. You can see that the books array has been "overwritten" by the `$lookup`.
123
+
124
+
```js
125
+
{
126
+
"name":"Richard Bruce Wright",
127
+
"sanitizedName":"richardbrucewright",
128
+
"books": [
129
+
{
130
+
"_id":"0002005018",
131
+
"title":"Clara Callan: A novel",
132
+
"authors": [
133
+
{
134
+
"_id": {
135
+
"$oid":"64cc2db4830ba29148da4c3b"
136
+
},
137
+
"name":"Richard Bruce Wright"
138
+
}
139
+
],
140
+
"genres": [
141
+
"Women Teachers",
142
+
"Young Women",
143
+
"Actresses",
144
+
"Sisters"
145
+
],
146
+
"pages":414,
147
+
"year":2001,
148
+
"synopsis":"Giller Prize Winner 2001. Richard B. Wright. A Phyllis Bruce Book.",
We can go ahead and remove the authors from the books array, as it is redundant:
238
+
239
+
```js
240
+
[
241
+
{$lookup: {
242
+
from:"books",
243
+
localField:"books",
244
+
foreignField:"_id",
245
+
as:"books"
246
+
}
247
+
},
248
+
{$unset:'books.authors'},
249
+
]
250
+
```
251
+
252
+
Now that our authors look the way we want, we can overwrite the authors collection using `$merge`
253
+
254
+
```js
255
+
[
256
+
{$lookup: {
257
+
from:"books",
258
+
localField:"books",
259
+
foreignField:"_id",
260
+
as:"books"
261
+
}
262
+
},
263
+
{$unset:'books.authors'},
264
+
{$merge: {
265
+
into:'authors',
266
+
on:'_id',
267
+
whenMatched:'replace',
268
+
}}
269
+
]
270
+
```
271
+
272
+
- we use the `_id` field to match documents
273
+
- we replace the existing ones with `replace`
274
+
275
+
:::warning
276
+
We should see a message telling us that the $merge operator will cause the pipeline to persist the results to the specified location. This stage changes data.
0 commit comments