File: //opt/go/pkg/mod/go.mongodb.org/
[email protected]/mongo/client_examples_test.go
// Copyright (C) MongoDB, Inc. 2017-present.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package mongo_test
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func ExampleClient() {
// Create a Client and execute a ListDatabases operation.
client, err := mongo.Connect(
context.TODO(),
options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal(err)
}
defer func() {
if err = client.Disconnect(context.TODO()); err != nil {
log.Fatal(err)
}
}()
collection := client.Database("db").Collection("coll")
result, err := collection.InsertOne(context.TODO(), bson.D{{"x", 1}})
if err != nil {
log.Fatal(err)
}
fmt.Printf("inserted ID: %v\n", result.InsertedID)
}
func ExampleConnect_ping() {
// Create a Client to a MongoDB server and use Ping to verify that the
// server is running.
clientOpts := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
defer func() {
if err = client.Disconnect(context.TODO()); err != nil {
log.Fatal(err)
}
}()
// Call Ping to verify that the deployment is up and the Client was
// configured successfully. As mentioned in the Ping documentation, this
// reduces application resiliency as the server may be temporarily
// unavailable when Ping is called.
if err = client.Ping(context.TODO(), readpref.Primary()); err != nil {
log.Fatal(err)
}
}
func ExampleConnect_replicaSet() {
// Create and connect a Client to a replica set deployment.
// Given this URI, the Go driver will first communicate with localhost:27017
// and use the response to discover any other members in the replica set.
// The URI in this example specifies multiple members of the replica set to
// increase resiliency as one of the members may be down when the
// application is started.
clientOpts := options.Client().ApplyURI(
"mongodb://localhost:27017,localhost:27018/?replicaSet=replset")
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_sharded() {
// Create and connect a Client to a sharded deployment.
// The URI for a sharded deployment should specify the mongos servers that
// the application wants to send messages to.
clientOpts := options.Client().ApplyURI(
"mongodb://localhost:27017,localhost:27018")
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_sRV() {
// Create and connect a Client using an SRV record.
// SRV records allow administrators to configure a single domain to return a
// list of host names. The driver will resolve SRV records prefixed with
// "_mongodb_tcp" and use the returned host names to build its view of the
// deployment.
// See https://www.mongodb.com/docs/manual/reference/connection-string/ for more
// information about SRV. Full support for SRV records with sharded clusters
// requires driver version 1.1.0 or higher.
clientOpts := options.Client().ApplyURI("mongodb+srv://mongodb.example.com")
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_direct() {
// Create a direct connection to a host. The driver will send all requests
// to that host and will not automatically discover other hosts in the
// deployment.
clientOpts := options.Client().ApplyURI(
"mongodb://localhost:27017/?connect=direct")
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_sCRAM() {
// Configure a Client with SCRAM authentication
// (https://www.mongodb.com/docs/manual/core/security-scram/).
// The default authentication database for SCRAM is "admin". This can be
// configured via the authSource query parameter in the URI or the
// AuthSource field in the options.Credential struct. SCRAM is the default
// auth mechanism so specifying a mechanism is not required.
// To configure auth via URI instead of a Credential, use
// "mongodb://user:password@localhost:27017".
credential := options.Credential{
Username: "user",
Password: "password",
}
clientOpts := options.Client().ApplyURI("mongodb://localhost:27017").
SetAuth(credential)
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_x509() {
// Configure a Client with X509 authentication
// (https://www.mongodb.com/docs/manual/core/security-x.509/).
// X509 can be configured with different sets of options in the connection
// string:
// 1. tlsCAFile (or SslCertificateAuthorityFile): Path to the file with
// either a single or bundle of certificate authorities to be considered
// trusted when making a TLS connection.
// 2. tlsCertificateKeyFile (or SslClientCertificateKeyFile): Path to the
// client certificate file or the client private key file. In the case that
// both are needed, the files should be concatenated.
// The SetAuth client option should also be used. The username field is
// optional. If it is not specified, it will be extracted from the
// certificate key file. The AuthSource is required to be $external.
caFilePath := "path/to/cafile"
certificateKeyFilePath := "path/to/client-certificate"
// To configure auth via a URI instead of a Credential, append
// "&authMechanism=MONGODB-X509" to the URI.
uri := "mongodb://host:port/?tlsCAFile=%s&tlsCertificateKeyFile=%s"
uri = fmt.Sprintf(uri, caFilePath, certificateKeyFilePath)
credential := options.Credential{
AuthMechanism: "MONGODB-X509",
}
clientOpts := options.Client().ApplyURI(uri).SetAuth(credential)
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_pLAIN() {
// Configure a Client with LDAP authentication
// (https://www.mongodb.com/docs/manual/core/authentication-mechanisms-enterprise/#security-auth-ldap).
// MongoDB Enterprise supports proxy authentication through an LDAP service
// that can be used through the PLAIN authentication mechanism.
// This auth mechanism sends the password in plaintext and therefore should
// only be used with TLS connections.
// To configure auth via a URI instead of a Credential, use
// "mongodb://ldap-user:ldap-pwd@localhost:27017/?authMechanism=PLAIN".
credential := options.Credential{
AuthMechanism: "PLAIN",
Username: "ldap-user",
Password: "ldap-pwd",
}
clientOpts := options.Client().ApplyURI("mongodb://localhost:27017").
SetAuth(credential)
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_kerberos() {
// Configure a Client with GSSAPI/SSPI authentication (https://www.mongodb.com/docs/manual/core/kerberos/).
// MongoDB Enterprise supports proxy authentication through a Kerberos
// service. Using Kerberos authentication requires the "gssapi" build tag
// and cgo support during compilation. The default service name for Kerberos
// is "mongodb". This can be configured via the AuthMechanismProperties
// field in the options.Credential struct or the authMechanismProperties URI
// parameter.
// For Linux, the libkrb5 library is required.
// Users can authenticate in one of two ways:
// 1. Use an explicit password. In this case, a password must be specified
// in the URI or the options.Credential struct and no further setup is
// required.
// 2. Store authentication keys in keytab files. To do this, the kinit
// binary should be used to initialize a credential cache for authenticating
// the user principal. In this example, the invocation would be
// "kinit [email protected]".
// To configure auth via a URI instead of a Credential, use
// "mongodb://drivers%[email protected]:27017/?authMechanism=GSSAPI".
credential := options.Credential{
AuthMechanism: "GSSAPI",
Username: "[email protected]",
}
uri := "mongo-server.example.com:27017"
clientOpts := options.Client().ApplyURI(uri).SetAuth(credential)
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
_ = client
}
func ExampleConnect_aWS() {
// Configure a Client with authentication using the MONGODB-AWS
// authentication mechanism. Credentials for this mechanism can come from
// one of four sources:
//
// 1. AWS IAM credentials (an access key ID and a secret access key)
//
// 2. Temporary AWS IAM credentials
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)
// obtained from an AWS Security Token Service (STS) Assume Role request
// (https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html)
//
// 3. AWS Lambda environment variables
// (https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime)
//
// 4. Temporary AWS IAM credentials assigned to an EC2 instance or ECS task
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html)
// The order in which the driver searches for credentials is:
//
// 1. Credentials passed through the URI
// 2. Environment variables
// 3. ECS endpoint if and only if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is
// set
// 4. EC2 endpoint
//
// The following examples set the appropriate credentials via the
// ClientOptions.SetAuth method. All of these credentials can be specified
// via the ClientOptions.ApplyURI method as well. If using ApplyURI, both
// the username and password must be URL encoded (see net.URL.QueryEscape())
// AWS IAM Credentials
// Applications can authenticate using AWS IAM credentials by providing a
// valid access key ID and secret access key pair as the username and
// password, respectively.
var accessKeyID, secretAccessKey string
awsCredential := options.Credential{
AuthMechanism: "MONGODB-AWS",
Username: accessKeyID,
Password: secretAccessKey,
}
awsIAMClient, err := mongo.Connect(
context.TODO(),
options.Client().SetAuth(awsCredential))
if err != nil {
panic(err)
}
_ = awsIAMClient
// AssumeRole
// Applications can authenticate using temporary credentials returned from
// an assume role request. These temporary credentials consist of an access
// key ID, a secret access key, and a security token.
var sessionToken string
assumeRoleCredential := options.Credential{
AuthMechanism: "MONGODB-AWS",
Username: accessKeyID,
Password: secretAccessKey,
AuthMechanismProperties: map[string]string{
"AWS_SESSION_TOKEN": sessionToken,
},
}
assumeRoleClient, err := mongo.Connect(
context.TODO(),
options.Client().SetAuth(assumeRoleCredential))
if err != nil {
panic(err)
}
_ = assumeRoleClient
// AWS Lambda (Environment Variables)
// When the username and password are not provided and the MONGODB-AWS
// mechanism is set, the client will fallback to using the environment
// variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN
// for the access key ID, secret access key, and session token,
// respectively. These environment variables must not be URL encoded.
// $ export AWS_ACCESS_KEY_ID=<accessKeyID>
// $ export AWS_SECRET_ACCESS_KEY=<secretAccessKey>
// $ export AWS_SESSION_TOKEN=<sessionToken>
envVariablesCredential := options.Credential{
AuthMechanism: "MONGODB-AWS",
}
envVariablesClient, err := mongo.Connect(
context.TODO(),
options.Client().SetAuth(envVariablesCredential))
if err != nil {
panic(err)
}
_ = envVariablesClient
// ECS Container or EC2 Instance
// Applications can authenticate from an ECS container or EC2 instance via
// temporary credentials assigned to the machine. If using an ECS container,
// the "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" environment variable must be
// set to a non-empty value. The driver will query the ECS or EC2 endpoint
// to obtain the relevant credentials.
ecCredential := options.Credential{
AuthMechanism: "MONGODB-AWS",
}
ecClient, err := mongo.Connect(
context.TODO(),
options.Client().SetAuth(ecCredential))
if err != nil {
panic(err)
}
_ = ecClient
}
func ExampleConnect_stableAPI() {
// Configure a Client with stable API.
//
// Stable API is a new feature in MongoDB 5.0 that allows user-selectable
// API versions, subsets of MongoDB server semantics, to be declared on a
// Client. During communication with a server, Clients with a declared API
// version will force that server to behave in a manner compatible with the
// API version. Declaring an API version on your Client can be used to
// ensure consistent responses from a server, providing long term API
// stability for an application.
//
// The declared API version is applied to all commands run through the
// Client, including those sent through the generic RunCommand helper.
// Specifying stable API options in the command document AND declaring
// an API version on the Client is not supported and will lead to undefined
// behavior. To run any command with a different API version or without
// declaring one, create a separate Client that declares the appropriate API
// version.
// ServerAPIOptions must be declared with an API version. ServerAPIVersion1
// is a constant equal to "1".
serverAPI := options.ServerAPI(options.ServerAPIVersion1)
serverAPIClient, err := mongo.Connect(
context.TODO(),
options.Client().SetServerAPIOptions(serverAPI))
if err != nil {
panic(err)
}
_ = serverAPIClient
// ServerAPIOptions can be declared with a Strict option. Declaring a strict
// API version will cause the MongoDB server to reject all commands that are
// not part of the declared API version. This includes command options and
// aggregation pipeline stages. For example, the following Distinct call
// would fail because the distinct command is not part of API version 1:
serverAPIStrict := options.ServerAPI(options.ServerAPIVersion1).
SetStrict(true)
serverAPIStrictClient, err := mongo.Connect(
context.TODO(),
options.Client().SetServerAPIOptions(serverAPIStrict))
if err != nil {
panic(err)
}
coll := serverAPIStrictClient.Database("db").Collection("coll")
// Fails with error: (APIStrictError) Provided apiStrict:true, but the
// command distinct is not in API Version 1
_, err = coll.Distinct(context.TODO(), "distinct", bson.D{})
log.Println(err)
// ServerAPIOptions can be declared with a DeprecationErrors option.
// DeprecationErrors can be used to enable command failures when using
// functionality that is deprecated in the declared API version. Note that
// at the time of this writing, no deprecations in API version 1 exist.
serverAPIDeprecation := options.ServerAPI(options.ServerAPIVersion1).
SetDeprecationErrors(true)
serverAPIDeprecationClient, err := mongo.Connect(
context.TODO(),
options.Client().SetServerAPIOptions(serverAPIDeprecation))
if err != nil {
panic(err)
}
_ = serverAPIDeprecationClient
}
func ExampleConnect_bSONOptions() {
// Configure a client that customizes the BSON marshal and unmarshal
// behavior.
// Specify BSON options that cause the driver to fallback to "json"
// struct tags if "bson" struct tags are missing, marshal nil Go maps as
// empty BSON documents, and marshals nil Go slices as empty BSON
// arrays.
bsonOpts := &options.BSONOptions{
UseJSONStructTags: true,
NilMapAsEmpty: true,
NilSliceAsEmpty: true,
}
clientOpts := options.Client().
ApplyURI("mongodb://localhost:27017").
SetBSONOptions(bsonOpts)
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
panic(err)
}
defer func() {
if err := client.Disconnect(context.TODO()); err != nil {
panic(err)
}
}()
coll := client.Database("db").Collection("coll")
// Define a struct that contains a map and a slice and uses "json" struct
// tags to specify field names.
type myDocument struct {
MyMap map[string]interface{} `json:"a"`
MySlice []string `json:"b"`
}
// Insert an instance of the struct with all empty fields. Expect the
// resulting BSON document to have a structure like {"a": {}, "b": []}
_, err = coll.InsertOne(context.TODO(), myDocument{})
if err != nil {
panic(err)
}
}