How to Construct MongoDB Queries from a String using Golang
Introduction to Creating MongoDB queries and filters in Golang
This tutorial will explain how to perform MongoDB queries with Golang. The article will cover how to create bson.M
(BSON map) objects from raw JSON strings and from primitve.M
BSON objects as well as how to pass those objects to the Golang driver’s method calls to query MongoDB documents. Both MongoDB and the Go driver must be installed on the same sever making the Go API calls.
Prerequisites for Making API Calls to MongoDB queries with the Golang Driver
MongoDB must be properly installed and running on the server making the Golang API calls. Type
mongod
into a terminal window to obtain information on the MongoDB daemon processes.A few documents in a MongoDB collection to use for querying the Golang script with the official MongoDB driver. The following is a screenshot of documents in a MongoDB collection:
- To access the attributes and fields of a Golang object, this tutorial utilizes a third-party library called oleiade/reflections to return high-level abstractions of Gonlang’s native, low-level
reflect
library. Enter the following command in a terminal or command-prompt window to install the package:
1 | go get gopkg.in/oleiade/reflections.v1 |
- Golang must be installed and the MongoDB project directory must be in Golang’s
$GOPATH
. Confirm both are installed and working with the following command:
1 | go get go.mongodb.org/mongo-driver/mongo |
References can be located by typing go help gopath
or $GOPATH
in a terminal window. Enter go help get
into a terminal window for additional help with Go’s get
command.
How to Import the MongoDB and Go packages in a Golang Script
Execute the folloing command to import the packages to allow MongoDB to create BSON filters, queries and unmarshaled strings in the main()
function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package main import ( "context" // manage multiple requests "encoding/json" // Use JSON encoding for bson. M string "fmt" // Println() function "log" "reflect" // get an object type // import 'mongo-go-driver' package libraries "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" // for BSON ObjectID "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) |
How to Declare a New Struct for the MongoDB Document Fields
Execute the following script to use Golang’s struct
datatype to map the MongoDB fields for the collection’s documents:
1 2 3 4 5 6 7 8 9 10 11 | type MongoFields struct { Key string `json:"key,omitempty"` // ObjectId() or objectid. ObjectID is deprecated--use primitive instead ID primitive. ObjectID `bson:"_id, omitempty"` // Use these field tags so Golang knows how to map MongoDB fields // `bson:"string field" json:"string field"` StringField string `bson:"string field" json:"string field"` IntField int `bson:"int field" json:"int field"` BoolField bool `bson:"bool field" json:"bool field"` } |
How to view a collection’s document fields in ‘Mongo Shell’
Enter the following script in Mongo Shell to confirm the exact format of the fields:
1 2 3 4 | mongo shell use SomeDatabase db["Some Collection"] db["Some Collection"].findOne() |
How to Declare the Golang Main() Function and Connect to MongoDB
Execute the below script to declare the main()
for the MongoDB API calls and document iteration. These commands will connect to the MongoDB server with mongo.Connect()
and then return a client instance that will be used to get a collection’s documents:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | func main() { // Declare host and port options to pass to the Connect() method clientOptions := options. Client(). ApplyURI("mongodb://localhost:27017") // Connect to the MongoDB and return Client instance client, err := mongo. Connect(context. TODO(), clientOptions) if err != nil { fmt. Println("mongo. Connect() ERROR:", err) log. Fatal(err) } // Declare Context object for the MongoDB API calls ctx := context. Background() // Access a MongoDB collection through a database col := client. Database("SomeDatabase"). Collection("Some Collection") |
NOTE: The "SomeDatabase"
and "Some Collection"
strings must be replaced with the correct names for the MongoDB database and collection.
How to Declare a BSON Map MongoDB Filter Object
Execute the following command to nest the BSON query into another BSON map object that has one of the collection’s field’s as its key:
1 | filter := bson. M{"int field": bson. M{"$gt":42}} |
How to Build a MongoDB Filter Query from a String in Golang
This section will explain how to create a BSON map object for a MongoDB query from a string in Golang and declare a Golang string consisting of a MongoDB JSON filter.
Use backticks to declare a raw string of a valid JSON object in Golang for the MongoDB filter and then instantiate an empty bson.M
object for the unmarshaled data to be stored by executing the following command:
1 2 3 4 5 | // Create a string using ` string escape ticks query := `{"$eq":"last value"}` // Declare an empty BSON Map object var bsonMap bson. M |
How to unmarshal a Golang string using the JSON package
Execute the following script to unmarshal the string and return primitive.M
:
1 2 3 4 5 6 7 8 9 | // Use the JSON package's Unmarshal() method err = json. Unmarshal([]byte(query), &bsonMap) if err != nil { log. Fatal("json. Unmarshal() ERROR:", err) } else { fmt. Println("bsonMap:", bsonMap) fmt. Println("bsonMap TYPE:", reflect. TypeOf(bsonMap)) fmt. Println("BSON:", reflect. TypeOf(bson. M{"int field": bson. M{"$gt":42}})) } |
How to declare a nested ‘bson. M’ MongoDB filter from the ‘primitive. M’ object returned by ‘json. Unmarshal()’
Execute the following command:
1 2 | // Nest the Unmarshalled BSON map inside another BSON object filter := bson. M{"string field": bsonMap} |
How to use the MongoDB Filter to Return a Cursor Object and Iterate the Documents
Execute the following script to have the Golang driver’s Find()
method return a cursor object and iterate the documents by passing a context object to the cursor’s Next()
method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Pass the filter to Find() to return a MongoDB cursor cursor, err := col. Find(ctx, filter) if err != nil { log. Fatal("col. Find ERROR:", err) } // Print cursor object fmt. Println("\ncursor TYPE:", reflect. TypeOf(cursor)) fmt. Println("cursor:", cursor) // iterate through all documents for cursor. Next(ctx) { var p MongoFields // Decode the document if err := cursor. Decode(&p); err != nil { log. Fatal("cursor. Decode ERROR:", err) } // Print the results of the iterated cursor object fmt. Printf("\nMongoFields: %+v\n", p) } } |
Conclusion
This tutorial explained how to create MongoDB queries with Golang using strings and BSON map
objects. The article covered how to create BSON map objects from raw JSON strings and primitve.M
BSON objects and explained how to pass those to the Golang driver’s method calls to query MongoDB documents. This tutorial also covered how to import the MongoDB and Go packages in a Golang script, how to unmarshal a Golang string using the JSON package, how to build a MongoDB filter query from a string in Golang and how to use the MongoDB filter to return a cursor object and iterate the documents. Remember that the "SomeDatabase"
and "Some Collection"
strings must be replaced with the correct names for the MongoDB database and collection.
Just the Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | package main import ( "context" // manage multiple requests "encoding/json" // Use JSON encoding for bson. M string "fmt" // Println() function "log" "reflect" // get an object type // import 'mongo-go-driver' package libraries "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" // for BSON ObjectID "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type MongoFields struct { Key string `json:"key,omitempty"` // ObjectId() or objectid. ObjectID is deprecated--use primitive instead ID primitive. ObjectID `bson:"_id, omitempty"` // Use these field tags so Golang knows how to map MongoDB fields // `bson:"string field" json:"string field"` StringField string `bson:"string field" json:"string field"` IntField int `bson:"int field" json:"int field"` BoolField bool `bson:"bool field" json:"bool field"` } func main() { // Declare host and port options to pass to the Connect() method clientOptions := options. Client(). ApplyURI("mongodb://localhost:27017") // Connect to the MongoDB and return Client instance client, err := mongo. Connect(context. TODO(), clientOptions) if err != nil { fmt. Println("mongo. Connect() ERROR:", err) log. Fatal(err) } // Declare Context object for the MongoDB API calls ctx := context. Background() // Access a MongoDB collection through a database col := client. Database("SomeDatabase"). Collection("Some Collection") // Typical BSON Map filter //filter := bson. M{"int field": bson. M{"$gt":42}} // Create a string using ` string escape ticks query := `{"$eq":"last value"}` // Declare an empty BSON Map object var bsonMap bson. M // Use the JSON package's Unmarshal() method err = json. Unmarshal([]byte(query), &bsonMap) if err != nil { log. Fatal("json. Unmarshal() ERROR:", err) } else { fmt. Println("bsonMap:", bsonMap) fmt. Println("bsonMap TYPE:", reflect. TypeOf(bsonMap)) fmt. Println("BSON:", reflect. TypeOf(bson. M{"int field": bson. M{"$gt": 42}})) } // Nest the Unmarshalled BSON map inside another BSON object filter := bson. M{"string field": bsonMap} // Pass the filter to Find() to return a MongoDB cursor cursor, err := col. Find(ctx, filter) if err != nil { log. Fatal("col. Find ERROR:", err) } // Print cursor object fmt. Println("\ncursor TYPE:", reflect. TypeOf(cursor)) fmt. Println("cursor:", cursor) // iterate through all documents for cursor. Next(ctx) { var p MongoFields // Decode the document if err := cursor. Decode(&p); err != nil { log. Fatal("cursor. Decode ERROR:", err) } // Print the results of the iterated cursor object fmt. Printf("\nMongoFields: %+v\n", p) } } |
Pilot the ObjectRocket Platform Free!
Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.
Get Started