Find Documents
For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt
Find Documents
Overview
In this guide, you can learn how to retrieve data from your MongoDB collections using read operations.
Read operations allow you to do the following:
-
Retrieve documents from your collections by using [find operations](https://www.mongodb.com/docs/drivers/go/current/crud/query/retrieve.md#std-label-golang-retrieve-find
-
Perform transformations on documents in your collections by using [aggregation operations](https://www.mongodb.com/docs/drivers/go/current/crud/query/retrieve.md#std-label-golang-retrieve-aggregation
Sample Data
The examples in this guide use the following Tea struct as a model for documents in the tea collection:
type Tea struct {
Item string `bson:"item,omitempty"`
Rating int32 `bson:"rating,omitempty"`
DateOrdered time.Time `bson:"date_ordered,omitempty"`
}
To run the examples in this guide, load these documents into the tea collection in the db database by using the following snippet:
coll := client.Database("db").Collection("tea")
docs := []any{
Tea{Item: "Masala", Rating: 10, DateOrdered: time.Date(2009, 11, 17, 0, 0, 0, 0, time.Local)},
Tea{Item: "Sencha", Rating: 7, DateOrdered: time.Date(2009, 11, 18, 0, 0, 0, 0, time.Local)},
Tea{Item: "Masala", Rating: 9, DateOrdered: time.Date(2009, 11, 12, 0, 0, 0, 0, time.Local)},
Tea{Item: "Masala", Rating: 8, DateOrdered: time.Date(2009, 12, 1, 0, 0, 0, 0, time.Local)},
Tea{Item: "Sencha", Rating: 10, DateOrdered: time.Date(2009, 12, 17, 0, 0, 0, 0, time.Local)},
Tea{Item: "Hibiscus", Rating: 4, DateOrdered: time.Date(2009, 12, 18, 0, 0, 0, 0, time.Local)},
}
result, err := coll.InsertMany(context.TODO(), docs)
Tip: Nonexistent Databases and Collections
If the necessary database and collection don't exist when you perform a write operation, the server implicitly creates them.
Each document describes the tea variety a customer ordered, their rating, and the date of the order. These descriptions correspond to the item, rating, and date_ordered fields.
Find Operations
Use find operations to retrieve data from MongoDB. Find operations consist of the Find() and FindOne() methods.
Find Multiple Documents
The Find() method expects you to pass a Context type and a query filter. The method returns all documents that match the filter as a Cursor type.
The following example passes a context, filter, and FindOptions to the Find() method, which performs the following actions:
-
Matches documents where the
ratingvalue is between5and9(exclusive) -
Sorts the matched documents in ascending order by
date_ordered
filter := bson.D{
{"$and",
bson.A{
bson.D{{"rating", bson.D{{"$gt", 5}}}},
bson.D{{"rating", bson.D{{"$lt", 9}}}},
}},
}
sort := bson.D{{"date_ordered", 1}}
opts := options.Find().SetSort(sort)
// Retrieves documents that match the filter and prints them as structs
cursor, err := coll.Find(context.TODO(), filter, opts)
if err != nil {
panic(err)
}
var results []Tea
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
res, _ := bson.MarshalExtJSON(result, false, false)
fmt.Println(string(res))
}
Output:
{"item":"Sencha","rating":7,"date_ordered":"2009-11-18T05:00:00Z"}
{"item":"Masala","rating":8,"date_ordered":"2009-12-01T05:00:00Z"}
To learn how to access data by using a cursor, see the [Access Data From a Cursor](https://www.mongodb.com/docs/drivers/go/current/crud/query/cursor.md#std-label-golang-cursor guide.
Find Multiple Documents Example: Full File
Note: Example Setup
This example connects to an instance of MongoDB by using a connection URI. To learn more about connecting to your MongoDB instance, see [Create a MongoClient](https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient.md#std-label-golang-mongoclient. This example also uses the restaurants collection in the sample_restaurants database included in the Atlas sample datasets. You can load them into your database on a free cluster on MongoDB Atlas by following the steps in [Get Started with Atlas.](https://www.mongodb.com/docs/get-started.md#std-label-unified-get-started
The following example finds all documents in the restaurants collection in which the value of cuisine is “Italian”. The example returns a cursor that references the matched documents and unpacks the documents into a slice:
// Retrieves documents that match a query filter by using the Go driver
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"os"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)
// Creates a Restaurant struct as a model for documents in the restaurants collection
type Restaurant struct {
ID bson.ObjectID `bson:"_id"`
Name string
RestaurantId string `bson:"restaurant_id"`
Cuisine string
Address any
Borough string
Grades any
}
func main() {
if err := godotenv.Load(); err != nil {
log.Println("No .env file found")
}
var uri string
if uri = os.Getenv("MONGODB_URI"); uri == "" {
log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable")
}
client, err := mongo.Connect(options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer func() {
if err = client.Disconnect(context.TODO()); err != nil {
panic(err)
}
}()
coll := client.Database("sample_restaurants").Collection("restaurants")
// Creates a query filter to match documents in which the "cuisine"
// is "Italian"
filter := bson.D{{"cuisine", "Italian"}}
// Retrieves documents that match the query filter
cursor, err := coll.Find(context.TODO(), filter)
if err != nil {
panic(err)
}
// Unpacks the cursor into a slice
var results []Restaurant
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
// Prints the results of the find operation as structs
for _, result := range results {
output, err := json.MarshalIndent(result, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", output)
}
}
Output:
// results truncated
...
{ ... , "Name" : "Epistrophy Cafe", "RestaurantId": "41117553", "Cuisine" : "Italian", ... },
{ ... , "Name" : "Remi", "RestaurantId": "41118090", "Cuisine" : "Italian", ... },
{ ... , "Name" : "Sant Ambroeus", "RestaurantId": "41120682", "Cuisine" : "Italian", ... },
...
Find One Document
The FindOne() method expects you to pass a Context type and a query filter. The method returns the first document that matches the filter as a SingleResult type.
The following example passes a context, filter, and FindOneOptions to the FindOne() method, which performs the following actions:
-
Matches documents where the
date_orderedvalue is on or before November 30, 2009 -
Skips the first two matched documents
filter := bson.D{{"date_ordered", bson.D{{"$lte", time.Date(2009, 11, 30, 0, 0, 0, 0, time.Local)}}}}
opts := options.FindOne().SetSkip(2)
// Retrieves a document that matches the filter and prints it as
// a struct
var result Tea
err = coll.FindOne(context.TODO(), filter, opts).Decode(&result)
if err != nil {
if err == mongo.ErrNoDocuments {
fmt.Println("No documents found")
} else {
panic(err)
}
}
res, _ := bson.MarshalExtJSON(result, false, false)
fmt.Println(string(res))
Output:
{"item":"Masala","rating":9,"date_ordered":"2009-11-12T05:00:00Z"}
For an example that uses FindOne() and queries by using a specific ObjectId value, see the [Find One by ObjectId Example](https://www.mongodb.com/docs/drivers/go/current/crud/query/retrieve.md#std-label-golang-find-one-by-id section of this page.
To learn how to access data from a SingleResult type, see [Unmarshalling](https://www.mongodb.com/docs/drivers/go/current/data-formats/bson.md#std-label-golang-bson-unmarshalling in the BSON guide.
Find One by ObjectId Example
This example defines an id variable with a value of type ObjectId and uses id to specify a query filter. The filter matches a document with an _id field value that corresponds to the id variable. This example queries for the following document based on its _id value:
{
_id: ObjectId('65170b42b99efdd0b07d42de'),
item: "Hibiscus",
rating : 4,
date_ordered : 2009-12-18T05:00:00.000+00:00
}
The following code passes the filter and a FindOneOptions instance as parameters to the FindOne() method to perform the following actions:
-
Match the document with the specified
ObjectIdvalue -
Project only the
ItemandRatingfields of the matched document
id, err := bson.ObjectIDFromHex("65170b42b99efdd0b07d42de")
if err != nil {
panic(err)
}
// Creates a filter to match a document that has the specified
// "_id" value
filter := bson.D{{"_id", id}}
opts := options.FindOne().SetProjection(bson.D{{"item", 1}, {"rating", 1}})
// Retrieves a document that matches the filter and prints it as
// a struct
var result Tea
err = coll.FindOne(context.TODO(), filter, opts).Decode(&result)
if err != nil {
if err == mongo.ErrNoDocuments {
fmt.Println("No documents found")
} else {
panic(err)
}
}
res, _ := bson.MarshalExtJSON(result, false, false)
fmt.Println(string(res))
Output:
{"item":"Hibiscus","rating":4}
Note:
The Go driver automatically generates a unique ObjectId value for each document's _id field, so your ObjectId value might differ from the preceding code example. For more information about the _id field, see the [_id Field](https://www.mongodb.com/docs/drivers/go/current/crud/insert.md#std-label-golang-insert-id section of the Insert a Document page.
Find One Document Example: Full File
Note: Example Setup
This example connects to an instance of MongoDB by using a connection URI. To learn more about connecting to your MongoDB instance, see [Create a MongoClient](https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient.md#std-label-golang-mongoclient. This example also uses the restaurants collection in the sample_restaurants database included in the Atlas sample datasets. You can load them into your database on a free cluster on MongoDB Atlas by following the steps in [Get Started with Atlas.](https://www.mongodb.com/docs/get-started.md#std-label-unified-get-started
The following example finds and returns the first document in the restaurants collection in which the value of name is “Bagels N Buns”:
// Retrieves a document that matches a query filter by using the Go driver
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"os"
"github.com/joho/godotenv"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)
// Creates a Restaurant struct as a model for documents in the restaurants collection
type Restaurant struct {
ID bson.ObjectID `bson:"_id"`
Name string
RestaurantId string `bson:"restaurant_id"`
Cuisine string
Address any
Borough string
Grades []any
}
func main() {
if err := godotenv.Load(); err != nil {
log.Println("No .env file found")
}
var uri string
if uri = os.Getenv("MONGODB_URI"); uri == "" {
log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/connect/mongoclient/#environment-variable")
}
client, err := mongo.Connect(options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer func() {
if err = client.Disconnect(context.TODO()); err != nil {
panic(err)
}
}()
coll := client.Database("sample_restaurants").Collection("restaurants")
// Creates a query filter to match documents in which the "name" is
// "Bagels N Buns"
filter := bson.D{{"name", "Bagels N Buns"}}
// Retrieves the first matching document
var result Restaurant
err = coll.FindOne(context.TODO(), filter).Decode(&result)
// Prints a message if no documents are matched or if any
// other errors occur during the operation
if err != nil {
if err == mongo.ErrNoDocuments {
return
}
panic(err)
}
output, err := json.MarshalIndent(result, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", output)
}
Output:
// results truncated
{
"ID": "5eb3d668b31de5d588f42950",
"Name": "Bagels N Buns",
"RestaurantId": "40363427"
"Address": [...],
"Borough": "Staten Island",
"Cuisine": "Delicatessen",
"Grades": [...]
}
Modify Behavior
You can modify the behavior of Find() and FindOne() by passing a FindOptions or FindOneOptions instance. If you don't specify any options, the driver uses the default values for each option.
You can configure the commonly used options in both types with the following methods:
| Method | Description |
|---|---|
SetCollation() |
The type of language collation to use when sorting results.Default: nil |
SetLimit() |
The maximum number of documents to return.Default: 0This option is not available for FindOneOptions. The FindOne() method internally uses SetLimit(-1). |
SetProjection() |
The fields to include in the returned documents.Default: nil |
SetSkip() |
The number of documents to skip.Default: 0 |
SetSort() |
The field and type of sort to order the matched documents. You can specify an ascending or descending sort.Default: none |
Aggregation Operations
Use aggregation operations to retrieve and transform data from MongoDB. Perform aggregation operations using the Aggregate() method.
Aggregation
The Aggregate() method expects you to pass a Context type and an aggregation pipeline. An aggregation pipeline defines how to transform data through stages. Some of the stages are matching documents, renaming fields, and grouping values.
The method returns the resulting documents in a Cursor type. If you omit the [$match](https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/#mongodb-pipeline-pipe.-match stage, the pipeline proceeds using all documents in the collection.
To learn how to access data in a cursor, see [Access Data From a Cursor.](https://www.mongodb.com/docs/drivers/go/current/crud/query/cursor.md#std-label-golang-cursor
Modify Behavior
The Aggregate() method optionally takes an AggregateOptions type, which represents options you can use to modify its behavior. If you don't specify any options, the driver uses the default values for each option.
The AggregateOptions type allows you to configure options with the following methods:
| Method | Description |
|---|---|
SetAllowDiskUse() |
Whether to write to temporary files.Default: false |
SetBatchSize() |
The number of documents to return in each batch.Default: none |
SetBypassDocumentValidation() |
Whether to allow the write to opt-out of document level validation.Default: false |
SetCollation() |
The type of language collation to use when sorting results.Default: nil |
SetMaxAwaitTime() |
The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query.Default: nil |
SetComment() |
An arbitrary string or document that allows you to trace the operation through the database profiler, currentOp, and logs.Default: “” |
SetHint() |
The index to use to scan for documents to retrieve.Default: nil |
SetLet() |
Specifies parameters for the aggregate expression, which improves command readability by separating the variables from the query text.Default: none |
Example
The following example passes a context and an aggregation pipeline that performs the following actions:
-
Groups reviews by item ordered
-
Calculates the average rating for each item
groupStage := bson.D{
{"$group", bson.D{
{"_id", "$item"},
{"average", bson.D{
{"$avg", "$rating"},
}},
}}}
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage})
if err != nil {
panic(err)
}
// Prints the average "rating" for each item
var results []bson.M
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
fmt.Printf("%v had an average rating of %v \n", result["_id"], result["average"])
}
Output:
Sencha had an average rating of 8.5
Hibiscus had an average rating of 4
Masala had an average rating of 9
To learn more about how to construct an aggregation pipeline, see the MongoDB server manual page on Aggregation.
Additional Information
To learn more about the operations mentioned, see the following guides:
-
[Specify a Query](https://www.mongodb.com/docs/drivers/go/current/crud/query/query-document.md#std-label-golang-query-document
-
[Access Data From a Cursor](https://www.mongodb.com/docs/drivers/go/current/crud/query/cursor.md#std-label-golang-cursor
-
[Specify Documents to Return](https://www.mongodb.com/docs/drivers/go/current/crud/query/specify-return-documents.md#std-label-golang-specify-documents-to-return
-
[Specify Which Fields to Return](https://www.mongodb.com/docs/drivers/go/current/crud/query/project.md#std-label-golang-project
-
[Aggregation](https://www.mongodb.com/docs/drivers/go/current/aggregation.md#std-label-golang-aggregation
-
[Collation](https://www.mongodb.com/docs/drivers/go/current/crud/configure.md#std-label-golang-collations
API Documentation
To learn more about any of the methods or types discussed in this guide, see the following API Documentation:
-
[FindOne()](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo#Collection.FindOne
-
[SingleResult](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo#SingleResult
-
[Find()](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo#Collection.Find
-
[FindOptions](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo/options#FindOptions
-
[FindOneOptions](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo/options#FindOneOptions
-
[Cursor](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo#Cursor
-
[Aggregate()](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo#Collection.Aggregate
-
[AggregateOptions](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2/mongo/options#AggregateOptions
