Skip to content

Commit 801ab2e

Browse files
authored
DOCSP-19061: adding a GridFS page (#119)
* page outline * writing code examples * DOCSP-19061: adding GridFS page * fixing rst errors * adding to TOC * code example formatting * addressing feedback * vale suggestions * typo * feedback * code example feedback * example format * code edits
1 parent 4abe19c commit 801ab2e

File tree

4 files changed

+399
-4
lines changed

4 files changed

+399
-4
lines changed

source/fundamentals.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Fundamentals
1616
/fundamentals/crud
1717
/fundamentals/aggregation
1818
/fundamentals/indexes
19+
/fundamentals/gridfs
1920
/fundamentals/time-series
2021

2122
..

source/fundamentals/gridfs.txt

Lines changed: 350 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,353 @@ GridFS
44

55
.. default-domain:: mongodb
66

7-
GridFS is a specification implemented by the driver that describes how to
8-
split files into chunks when storing them and reassemble them when retrieving
9-
them. The driver implementation of GridFS is an abstraction that manages
10-
the operations and organization of the file storage.
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 2
11+
:class: singlecol
12+
13+
Overview
14+
--------
15+
16+
In this guide, you can learn how to store and retrieve large files in
17+
MongoDB using the **GridFS** specification. GridFS splits large files
18+
into chunks and stores each chunk as a separate document. When you query
19+
GridFS for a file, the driver will reassemble the chunks as needed. The
20+
driver implementation of GridFS is an abstraction that manages the operations
21+
and organization of the file storage.
22+
23+
Use GridFS if the size of your files exceeds the BSON document size limit of
24+
16 MB. GridFS is also useful for accessing files without loading the entire file
25+
into memory. For more detailed information on whether GridFS is suitable for
26+
your use case, see the :manual:`GridFS server manual page </core/gridfs>`.
27+
28+
How GridFS Works
29+
----------------
30+
31+
GridFS organizes files in a **bucket**, a group of MongoDB collections
32+
that contain the chunks of files and information describing them. The
33+
bucket contains the following collections:
34+
35+
- The ``chunks`` collection, which stores the binary file chunks.
36+
- The ``files`` collection, which stores the file metadata.
37+
38+
When you create a new GridFS bucket, the driver creates the preceding
39+
collections. The default bucket name ``fs`` prefixes the collection names,
40+
unless you specify a different bucket name. The driver creates the new GridFS
41+
bucket during the first write operation.
42+
43+
The driver also creates an index on each collection to ensure efficient
44+
retrieval of the files and related metadata. The driver creates indexes
45+
if they do not already exist and when the bucket is empty. For more information
46+
on GridFS indexes, see the server manual page on :manual:`GridFS Indexes </core/gridfs/#gridfs-indexes>`.
47+
48+
When storing files with GridFS, the driver splits the files into smaller
49+
chunks, each represented by a separate document in the ``chunks`` collection.
50+
It also creates a document in the ``files`` collection that contains
51+
a file ID, file name, and other file metadata. The following diagram shows
52+
how GridFS splits the uploaded files:
53+
54+
.. figure:: /includes/figures/GridFS-upload.png
55+
:alt: A diagram that shows how GridFS uploads a file to a bucket
56+
57+
When retrieving files, GridFS fetches the metadata from the ``files``
58+
collection in the specified bucket, then uses that information to reconstruct
59+
the file from documents in the ``chunks`` collection. You can read the file
60+
into memory or output it to a stream.
61+
62+
Use GridFS
63+
----------
64+
65+
To learn about GridFS operations and how to perform them, navigate to the
66+
following sections:
67+
68+
- :ref:`<golang-create-bucket>`
69+
- :ref:`<golang-upload-files>`
70+
- :ref:`<golang-retrieve-info>`
71+
- :ref:`<golang-download-files>`
72+
- :ref:`<golang-rename-files>`
73+
- :ref:`<golang-delete-files>`
74+
- :ref:`<golang-delete-bucket>`
75+
76+
.. _golang-create-bucket:
77+
78+
Create a GridFS Bucket
79+
~~~~~~~~~~~~~~~~~~~~~~
80+
81+
To store or retrieve files from GridFS, create a bucket or get a reference to
82+
an existing bucket on a MongoDB database. To create a ``GridFSBucket`` instance,
83+
call the ``NewBucket()`` method with a database parameter:
84+
85+
.. code-block:: go
86+
87+
db := client.Database("myDB")
88+
bucket, err := gridfs.NewBucket(db)
89+
if err != nil {
90+
panic(err)
91+
}
92+
93+
.. note::
94+
95+
If a GridFS bucket already exists, the ``NewBucket()`` method returns a
96+
reference to the bucket rather than instantiating a new one.
97+
98+
By default, the new bucket is named ``fs``. To instantiate a bucket with a
99+
custom name, call the ``SetName()`` method on a ``BucketOptions`` instance as
100+
follows:
101+
102+
.. code-block:: go
103+
104+
db := client.Database("myDB")
105+
opts := options.GridFSBucket().SetName("custom name")
106+
bucket, err := gridfs.NewBucket(db, opts)
107+
108+
if err != nil {
109+
panic(err)
110+
}
111+
112+
.. _golang-upload-files:
113+
114+
Upload Files
115+
~~~~~~~~~~~~
116+
117+
You can upload a file into a GridFS bucket in one of the following ways:
118+
119+
- Use the ``UploadFromStream()`` method, which reads from an input stream.
120+
- Use the ``OpenUploadStream()`` method, which writes to an output stream.
121+
122+
For either upload process, you can specify configuration information on an instance
123+
of ``UploadOptions``. For a full list of ``UploadOptions`` fields, visit the
124+
`API documentation <{+api+}/mongo/options#UploadOptions>`__.
125+
126+
Upload with an Input Stream
127+
```````````````````````````
128+
129+
To upload a file with an input stream, use the ``UploadFromStream()`` method
130+
with the following parameters:
131+
132+
- Your file name
133+
- An ``io.Reader``, with your opened file as a parameter
134+
- An optional ``opts`` parameter to modify the behavior of ``UploadFromStream()``
135+
136+
The following code example reads from a file called ``file.txt`` and uploads the
137+
content to a GridFS bucket. It uses an ``opts`` parameter to set file metadata:
138+
139+
.. io-code-block::
140+
:copyable: true
141+
142+
.. input::
143+
:language: go
144+
145+
file, err := os.Open("path/to/file.txt")
146+
uploadOpts := options.GridFSUpload().SetMetadata(bson.D{{"metadata tag", "first"}})
147+
148+
objectID, err := bucket.UploadFromStream("file.txt", io.Reader(file),
149+
uploadOpts)
150+
if err != nil {
151+
panic(err)
152+
}
153+
154+
fmt.Printf("New file uploaded with ID %s", objectID)
155+
156+
.. output::
157+
:language: none
158+
:visible: false
159+
160+
New file uploaded with ID 62e005408bc04f3816b8bcd2
161+
162+
.. note::
163+
164+
The driver uniquely generates each object ID number. The ID number outputted
165+
will resemble the sample output but varies with each file and user.
166+
167+
Upload with an Output Stream
168+
````````````````````````````
169+
170+
To upload a file with an output stream, use the ``OpenUploadStream()`` method
171+
with the following parameters:
172+
173+
- Your file name
174+
- An optional ``opts`` parameter to modify the behavior of ``OpenUploadStream()``
175+
176+
The following code example opens an upload stream on a GridFS bucket and sets
177+
the number of bytes in each chunk with an ``opts`` parameter. Then, it calls
178+
the ``Write()`` method on the content of ``file.txt`` to write its content to
179+
the stream:
180+
181+
.. literalinclude:: /includes/fundamentals/code-snippets/gridfs.go
182+
:language: go
183+
:dedent:
184+
:start-after: begin OpenUploadStream example
185+
:end-before: end OpenUploadStream example
186+
187+
.. _golang-retrieve-info:
188+
189+
Retrieve File Information
190+
~~~~~~~~~~~~~~~~~~~~~~~~~
191+
192+
You can retrieve file metadata stored in the ``files`` collection of the GridFS
193+
bucket. Each document in the ``files`` collection contains the following
194+
information:
195+
196+
- The file ID
197+
- The file length
198+
- The maximum chunk size
199+
- The upload date and time
200+
- The file name
201+
- A ``metadata`` document in which you can store any other information
202+
203+
To retrieve file data, call the ``Find()`` method on a ``GridFSBucket``
204+
instance. You can pass a query filter as an argument to ``Find()`` to match
205+
only certain file documents.
206+
207+
.. note::
208+
209+
The ``Find()`` method requires a query filter as a parameter. To match all
210+
documents in the ``files`` collection, pass an empty query filter to ``Find()``.
211+
212+
The following example retrieves the file name and length of documents in the
213+
``files`` collection with ``length`` values greater than ``1500``:
214+
215+
.. code-block:: go
216+
217+
filter := bson.D{{"length", bson.D{{"$gt", 1500}}}}
218+
cursor, err := bucket.Find(filter)
219+
if err != nil {
220+
panic(err)
221+
}
222+
223+
type gridfsFile struct {
224+
Name string `bson:"filename"`
225+
Length int64 `bson:"length"`
226+
}
227+
var foundFiles []gridfsFile
228+
if err = cursor.All(context.TODO(), &foundFiles); err != nil {
229+
panic(err)
230+
}
231+
232+
for _, file := range foundFiles {
233+
fmt.Printf("filename: %s, length: %d\n", file.Name, file.Length)
234+
}
235+
236+
.. _golang-download-files:
237+
238+
Download Files
239+
~~~~~~~~~~~~~~
240+
241+
You can download a GridFS file in one of the following ways:
242+
243+
- Use the ``DowloadToStream()`` method to download a file to an output stream.
244+
- Use the ``OpenDownloadStream()`` method to open an input stream.
245+
246+
Download a File to an Output Stream
247+
```````````````````````````````````
248+
249+
You can download a file in a GridFS bucket directly to an output stream using the
250+
``DownloadToStream()`` method. ``DownloadToStream()`` takes a file ID and an
251+
``io.Writer`` as parameters. The method downloads the file with the specified
252+
file ID and writes to the ``io.Writer``.
253+
254+
The following example downloads a file and writes to a file buffer:
255+
256+
.. code-block:: go
257+
258+
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88")
259+
fileBuffer := bytes.NewBuffer(nil)
260+
if _, err := bucket.DownloadToStream(id, fileBuffer); err != nil {
261+
panic(err)
262+
}
263+
264+
Download a File to an Input Stream
265+
``````````````````````````````````
266+
267+
You can download a file in a GridFS bucket to memory with an input stream using
268+
the ``OpenDownloadStream()`` method. ``OpenDownloadStream()`` takes a file ID as
269+
a parameter and returns an input stream from which you can read the file.
270+
271+
The following example downloads a file into memory and reads its contents:
272+
273+
.. code-block:: go
274+
275+
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88")
276+
downloadStream, err := bucket.OpenDownloadStream(id)
277+
if err != nil {
278+
panic(err)
279+
}
280+
281+
fileBytes := make([]byte, 1024)
282+
if _, err := downloadStream.Read(fileBytes); err != nil {
283+
panic(err)
284+
}
285+
286+
.. _golang-rename-files:
287+
288+
Rename Files
289+
~~~~~~~~~~~~
290+
291+
You can update the name of a GridFS file in your bucket by using the ``Rename()``
292+
method. Pass a file ID value and a new ``filename`` value as arguments to
293+
``Rename()``.
294+
295+
The following example renames a file to ``"mongodbTutorial.zip"``:
296+
297+
.. code-block:: go
298+
299+
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88")
300+
if err := bucket.Rename(id, "mongodbTutorial.zip"); err != nil {
301+
panic(err)
302+
}
303+
304+
.. _golang-delete-files:
305+
306+
Delete Files
307+
~~~~~~~~~~~~
308+
309+
You can remove a file from your GridFS bucket by using the ``Delete()`` method.
310+
Pass a file ID value as an argument to ``Delete()``.
311+
312+
The following example deletes a file:
313+
314+
.. code-block:: go
315+
316+
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88")
317+
if err := bucket.Delete(id); err != nil {
318+
panic(err)
319+
}
320+
321+
.. _golang-delete-bucket:
322+
323+
Delete a GridFS Bucket
324+
~~~~~~~~~~~~~~~~~~~~~~
325+
326+
You can delete a GridFS bucket by using the ``Drop()`` method.
327+
328+
The following code example deletes a GridFS bucket:
329+
330+
.. code-block:: go
331+
332+
if err := bucket.Drop(); err != nil {
333+
panic(err)
334+
}
335+
336+
337+
Additional Resources
338+
--------------------
339+
340+
To learn more about GridFS and its operations, visit the :manual:`GridFS manual page </core/gridfs>`.
341+
342+
API Documentation
343+
~~~~~~~~~~~~~~~~~
344+
345+
To learn more about the methods or types discussed in this guide, see the following
346+
API Documentation:
347+
348+
- `NewBucket() <{+api+}/mongo/gridfs#NewBucket>`__
349+
- `OpenUploadStream() <{+api+}/mongo/gridfs#Bucket.OpenUploadStream>`__
350+
- `UploadFromStream() <{+api+}/mongo/gridfs#Bucket.UploadFromStream>`__
351+
- `Find() <{+api+}/mongo/gridfs#Bucket.Find>`__
352+
- `OpenDownloadStream() <{+api+}/mongo/gridfs#Bucket.OpenUploadStream>`__
353+
- `DownloadToStream() <{+api+}/mongo/gridfs#Bucket.DownloadToStream>`__
354+
- `Rename() <{+api+}/mongo/gridfs#Bucket.Rename>`__
355+
- `Delete() <{+api+}/mongo/gridfs#Bucket.Delete>`__
356+
- `Drop() <{+api+}/mongo/gridfs#Bucket.Drop>`__
9.01 KB
Loading

0 commit comments

Comments
 (0)