Work with BSON
On this page
Overview
In this guide, you can learn about how the Go Driver handles conversions between BSON and Go values. The process of converting a Go value to BSON is called marshalling, while the reverse process is called unmarshalling.
You should read this guide if you want to learn more about how the Go Driver represents BSON data or need to adjust default marshalling and unmarshalling behaviors.
Data Types
MongoDB stores documents in a binary representation called BSON that allows for easy and flexible data processing.
The Go Driver provides four main types for working with BSON data:
D
: An ordered representation of a BSON document (slice)M
: An unordered representation of a BSON document (map)A
: An ordered representation of a BSON arrayE
: A single element inside a D type
The following example demonstrates how to construct a query filter using the
bson.D
type to match documents with a quantity
field value greater
than 100:
filter := bson.D{{"quantity", bson.D{{"$gt", 100}}}}
To learn more about how the Go Driver handles BSON data, see the bson package API documentation.
Struct Tags
In Go, a struct is a collection of data fields with declared data types. The Go Driver can marshal/unmarshal structs and other native Go types to/from BSON using a configurable codec system.
You can modify the default marshalling and unmarshalling behavior of the Go Driver using struct tags, which are optional pieces of metadata attached to struct fields. The most common use of struct tags is for specifying the field name in the BSON document that corresponds to the struct field. The following table describes the additional struct tags that you can use with the Go Driver:
Struct Tag | Description |
---|---|
omitempty | The field will not be marshalled if it is set to the zero value
corresponding to the field type. |
minsize | If the field type is type int64, uint, uint32, or uint64 and the value of
the field can fit in a signed int32, the field will be serialized
as a BSON int32 rather than a BSON int64. If the value can't fit
in a signed int32, this tag is ignored. |
truncate | If the field type is a non-float numeric type, BSON doubles
unmarshalled into that field will be truncated at the decimal point. |
inline | If the field type is a struct or map field, the field will be
flattened when marshalling and unflattened when unmarshalling. |
Without additional instruction from struct tags, the Go Driver will marshal structs using the following rules:
The Go Driver only marshals and unmarshals exported fields.
The Go Driver generates BSON key using the lowercase of the corresponding struct field.
The Go Driver marshals embedded struct fields as subdocuments. Each key is the lowercase of the field's type.
The Go Driver marshals a pointer field as the underlying type if the pointer is non-nil. If the pointer is nil, the driver marshals it as a BSON null value.
When unmarshalling, the Go Driver follows these D/M type mappings for fields of type
interface{}
. The driver unmarshals BSON documents unmarshalled into aninterface{}
field as aD
type.
Unmarshalling
You can unmarshal BSON documents by using the Decode()
method on the
result of the FindOne
method or any *mongo.Cursor
instance.
The Decode()
method returns an error
type which
contains one of the following values:
nil
if a document matched your query, and there were no errors retrieving and unmarshalling the document.If the driver retrieved your document but could not unmarshal your result, the
Decode()
method returns the unmarshalling error.If there was an error retrieving your document during execution of the
FindOne()
method, the error propagates to theDecode()
method and theDecode()
method returns the error.
When used on the SingleResult
type returned by the FindOne()
method, Decode()
can also return the ErrNoDocuments
error if no
documents matched the query filter.
The following example demonstrates how you can use the Decode()
method to unmarshal and read the result of a simple FindOne()
operation:
coll := client.Database("school").Collection("students") filter := bson.D{{"age", 8}} var result bson.D err := coll.FindOne(context.TODO(), filter).Decode(&result) fmt.Println(result)
The Cursor
type also uses the All()
method, which unmarshals all
documents stored in the cursor into an array at the same time.
The bson
package includes a family of
Marshal()
and Unmarshal()
methods that work with BSON-encoded data
of []byte
type.
The following code demonstrates how you can unmarshal BSON back into a
user-defined struct by using methods from the bson
package:
type Item struct { Category string Quantity int32 } doc, err := bson.Marshal(bson.D{{"category", "plate"}, {"quantity", 6}}) var test Item err = bson.Unmarshal(doc, &test) fmt.Printf("Unmarshalled Struct:\n%+v\n", test)
Note
You can use the Raw
type to retrieve elements from a BSON
document byte slice without unmarshalling it to a Go value. This can
be useful if you need to look up individual elements without
unmarshalling the entire BSON document.
To learn more about the marshalling and unmarshalling methods used with the
Cursor
type, see the Cursor API documentation
To learn more about the marshalling and unmarshalling methods in the
bson
package, see the bson API documentation