How to Use Golang Structs with MongoDB

Photograph by Ana Abad on Unsplash

To reveal using Golang structs with MongoDB, I’ve created a easy electronic mail autoresponder for example. We’ve got some contacts to whom we want to ship emails. As well as, now we have emails to ship at particular occasions, with topic and content material. Lastly, we even have a sequence that connects the contacts to the emails.

Through the use of Golang structs, we decrease using BSON in our code and enhance the usability of the outcomes from the database queries. This text will be seen as a continuation of a earlier article referred to as “How To Use Go With MongoDB.”

In what follows, I am going over the code of somewhat demo, piece by piece.

To start out, we’ll import the required Golang packages.

We have to import these libraries to do the next:

  • context is important to create a context for the MongoDB operations.
  • bson for serializing the information that’s despatched to the MongoDB server.
  • mongo to take care of connecting to the MongoDB server and establishing the database and collections.

As a substitute of utilizing bson serializations as we did in the previous article, the thought right here is to make use of Golang structs. These structs want to make use of bson annotations for this to work accurately.

Within the above piece of code, we are able to see numerous bson annotations.

These annotations all observe the identical sample:

bson:"<fieldname>,omitempty" the place <fieldname> is the precise discipline identify within the database and omitempty signifies that the sector will probably be omitted if no worth is given.

Observe that the annotations are additionally between downward accent symbols and that there are no areas.

As a substitute of utilizing omitempty, you need to use different struct tags (or use none in any respect). Learn extra about that here.

In traces 2, 9, and 16, we set the kind of the ID fields to be primitive.ObjectID . By doing this, we inform BSON that these fields will probably be precise MongoDB ObjectIDs .

Additionally, the _id database fields will at all times be stuffed in though we’ll omit them when defining cases of those structs (extra about that later). The MongoDB server will fill in these fields and provides them distinctive ObjectIDs. We’ll be utilizing these ObjectIDs to deal with the person paperwork within the collections.

In line 5, we create a slice of strings. This slice will robotically be transformed to a bson.A (BSON array).

In line 10, you’ll be able to see that additionally it is potential to make use of a discipline of time.Time.

In traces 17–18, we’ll place references to different paperwork within the database. These references will probably be lists of ObjectIDs. Right here, I’m displaying you two methods to do that.

You need to use both []interface which is essentially the most generic method by which you are able to do this. The hazard is you can put any values right here — together with integers, strings, and so forth.

The opposite risk is to make use of []primitive.ObjectID. It is a particular method of declaring the sort. Now solely, ObjectIDs will probably be accepted. The issue with this strategy is that we’ll want to jot down somewhat extra code afterward.

The very first thing to do within the major() operate is to connect with the MongoDB server and create the database with the collections that can comprise the paperwork.

In traces 1 and a couple of, we create a brand new consumer for MongoDB utilizing NewClient() and the right URI. Observe that my MongoDB is operating on localhost with port 27017. No username or passwords have been set, as that is my take a look at server.

In line 7, we create a context utilizing context.TODO(). That is essentially the most fundamental context potential.

In line 9, we let the consumer connect with the MongoDB server with the given context.

In line 14, we defer disconnecting from the MongoDB server. On condition that the Disconnect() operate is deferred, it is going to be executed in spite of everything different statements within the major() operate have been run.

In line 16, we create a database referred to as autoresponder.

In traces 17–19, we make three collections inside this database. These collections are referred to as contacts, emails, and sequences respectively.

In traces 21–23, we defer dropping the database collections. That is just for our instance right here, as I don’t need my database to replenish each time I run the code and take a look at out new stuff. Please take away these traces for those who want to maintain the information within the database.

Inserting the Contacts into the database

Let’s create some mock contacts and insert them into the contactsCollection.

In traces 1–17, we create three contacts (‘paperwork’ in MongoDB terminology) in the identical method as we might create common structs. Discover how this differs from utilizing BSON as we did here (scroll midway down the web page).

In line 19, we then insert these contacts into the contact assortment utilizing InsertMany() as we wish to insert a number of paperwork directly.

In line 24, we get the ids of the inserted contacts utilizing the consequence insertResult from line 19 and the property InsertedIDs.

In line 26, we create a slice of sort []primitive.ObjectID referred to as contactIDs_.

In traces 17–29, we loop over the returned contactIDs , forged every aspect as an primitive.ObjectID and append it to contactIDs_. Apparently, typecasting from []interface to []primitive.ObjectID can’t be accomplished; that’s why we use the for loop.

Observe right here that we didn’t outline the IDs ourselves. When inserting the paperwork, MongoDB robotically assigned the IDs. These ids are saved within the _id discipline the precise database and will also be accessed within the struct by utilizing the ID property.

In line 31, we print out the contactIDs_ slice to reveal that we inserted the three contacts and that the sort is right.

We will additionally test this utilizing MongoDB Compass.

Inserting the Emails into the database

Now, let’s additionally insert some emails into the emailsCollection.

This occurs just about analogously to the insertion of the contacts.

To notice right here is that in traces 3, 7, and 11, we use time.Now() as a variable worth.

In line 21, we retrieve the emailIDs from the return results of the InsertMany() operation in line 16.

Inserting the sequence into the database

Lastly, let’s additionally insert one sequence within the sequencesCollection.

In line 1, we create a sequence utilizing the Sequence struct. On this struct, we put the emailIDs and the contactIDS_ that we retrieved from the insertion outcomes beforehand.

In line 3, we use InsertOne() as an alternative of InsertMany() that we used beforehand.

Discover particular Contacts

Within the code under, I reveal learn how to discover contacts utilizing a customized filter.

In line 2, we use the Discover() operate to search out all contacts that fulfill the filter bson.M"tags": "Buyer". With this filter, we’ll discover all contacts which have "Buyer" of their tag record.

You may, in fact, adapt this filter to your wants. If you wish to discover all contacts, you need to use bson.M. Or, for those who want to discover the contact who has mm@instance.com as an electronic mail deal with, you’ll be able to write bson.M"electronic mail":"mm@instance.com".

As well as, as an alternative of utilizing the bson.M format on your filter, you would use bson.D. Extra on this here.

In line 7, the outcomes from the question are loaded into the []Contact slice referred to as contacts by utilizing All().

In traces 11–15, we merely print out a few of the properties of the Contact structs, as we might do with any struct.

Like this, we are able to maximize using Golang structs and cut back using BSON to the filters within the queries.

Discover the sequence and retrieve the contacts and emails

Under, we get better the sequence from the sequencesCollection. We get the e-mail IDs and the receivers’ IDs from this sequence. These IDs are then used to retrieve the respective emails and contacts.

In traces 10–13, we use the [0] as just one sequence was returned.

In traces 17 and 23, we use FindOne() along with bson.M"_id": <id> to search out and filter the emails and contacts solely to search out one particular doc primarily based on its ObjectID (in <id>). As there is just one consequence, we are able to additionally use Decode() as an alternative of All() to extract the outcomes into E mail and Contact struct, respectively.

Under you will discover the whole code. Be sure to have a MongoDB server operating on mongodb://localhost:27017 earlier than executing the code — or change the URI.

More Posts