A newer version of this documentation is available.

View Latest

Managing Clusters Using the Go SDK with Couchbase Server

The primary means for managing clusters is through the Couchbase Web UI which provides an easy to use interface for adding, removing, monitoring and modifying buckets. In some instances you may wish to have a programmatic interface. For example, if you wish to manage a cluster from a setup script, or if you are setting up buckets in test scaffolding.

The Go SDK also comes with some convenience functionality for common Couchbase management requests.

Management operations in the Go SDK may be performed through several interfaces depending on the object:

  • ClusterManager interface (obtained via Cluster.Manager(username, password string)) (administrative username and password).

  • BucketManager interface (obtained via Bucket.Manager(username, password string)) (cluster or bucket credentials).

Creating and Removing Buckets

The ClusterManager interface may be used to create and delete buckets from the Couchbase cluster. It is instantiated through the Cluster's Manager method, providing the administrative username and password.

myCluster, _ := gocb.Connect("couchbase://localhost")
clusterManager = myCluster.Manager("Administrator", "123456")

To create a bucket, use the ClusterManager's InsertBucket(settings *BucketSettings) method. The BucketSettings struct is also used to expose information about existing buckets (ClusterManager.GetBuckets() returns a slice of settings) or to update an existing bucket (ClusterManager.UpdateBucket(settings *BucketSettings)).

Note that any property that is not explicitly set when building the BucketSettings will use the default value. In the case of the update, this is not necessarily the currently configured value, so you should be careful to set all properties to their correct expected values when updating an existing bucket configuration.

Only name and type parameters are mandatory for the BucketSettings. Here is the list of parameters available:

  • Name: The name of the bucket (mandatory to create one, cannot be updated).

  • Type: The type of the bucket (mandatory to create one, cannot be changed). Defaults to BucketType.Couchbase, but can also be BucketType.Memcached to create a cache bucket.

  • Quota: How much memory should each node use for the bucket. This number is specified in megabytes.

  • Password: If specified, makes this bucket password protected, forcing future connects (using the Bucket) interface to specify the password parameter.

  • FlushEnabled: Enables the BucketManager#flush() operation to be performed on this bucket (see the Flushing Buckets section below).

  • Replicas: The number of replicas to use for the bucket.

  • IndexReplicas: Wether or not to replicate indexes.

The following example updates an existing "hello" bucket (notice how all parameters are set):

bucketSettings := BucketSettings {
        FlushEnabled: true,
        IndexReplicas: true,
        Name: "hello",
        Password: "",
        Quota: 120,
        Replicas: 1,
        Type: BucketType.Couchbase
}

manager := cluster.Manager("Administrator", "123456")
err := manager.UpdateBucket(bucketSettings)

Once you no longer need to use the bucket, you may delete the bucket using the ClusterManager.RemoveBucket(name string) method:

clusterManager.RemoveBucket("hello");

Flushing Buckets

When a bucket is flushed, all content is removed. Because this operation is potentially dangerous it is disabled by default for each bucket. Bucket flushing may be useful in test environments where it becomes a simpler alternative to removing and creating a test bucket. You may enable bucket flushing on a per-bucket basis using the Couchbase Web Console or when creating a bucket.

You may flush a bucket in the Go SDK by using the BucketManager.Flush() method.

The flush operation may fail if the bucket does not have flush enabled:

{
    "_": "Flush is disabled for the bucket"
}

Index Management

You can create and drop N1QL indexes using the SDK. This is especially useful when setting up new applications, or simply when ensuring that a given bucket has certain indexes defined. Indexes can be defined using actual N1QL statements or by using convenience functions within the SDK.

You can manage indexes in the Go SDK using the BucketManager interface, with its various N1QL related methods: GetIndexes(), CreateIndex(...), etc...

The following example creates a N1QL secondary index named "fooBar" on the "test" bucket, indexing fields "foo" and "bar":

myCluster, _ := gocb.Connect("couchbase://localhost")
testBucket, _ := myCluster.OpenBucket("test")
testManager := testBucket.BucketManager()

//true, false at the end: ignore errors if the index exists, don't defer the creation
testManager.CreateIndex("fooBar", string[]{ "foo", "bar" }, true, false);

View Management

Views are stored in design documents. The SDK provides convenient methods to create, retrieve, and remove design documents. To set up views, you create design documents that contain one or more view definitions, and then insert the design documents into a bucket. Each view in a design document is represented by a name and a set of MapReduce functions. The mandatory map function describes how to select and transform the data from the bucket, and the optional reduce function describes how to aggregate the results.

In the Go SDK, design documents are represented by the DesignDocument and View structs. All operations on design documents are performed on a BucketManager instance.

To inspect design documents, you can either retrieve them by name (bucketManager.GetDesignDocument("landmarks")) or iterate through a slice of documents (bucketManager.GetDesignDocuments()).

To create or update design documents, use the InsertDesignDocument(ddoc *DesignDocument) and UpsertDesignDocument(ddoc *DesignDocument) methods.

The following example inserts a design document with two regular views and one spatial view into a bucket named travel-sample:

//(note: obtaining the bucketManager is omitted in this snippet)
// Initialize design document
designDoc := DesignDocument {
        Name: "landmarks",
        Views: map[string]View {
                "by_country": View {
                        Map: "function (doc, meta) { if (doc.type == 'landmark') { emit([doc.country, doc.city], null); } }",
                        Reduce: nil
                },
                "by_activity": View {
                        Map: "function (doc, meta) { if (doc.type == 'landmark') { emit(doc.activity, null); } }",
                        Reduce: "_count"
                }
        },
        SpatialViews: map[string]View {
                "by_coordinates": View {
                        Map: "function (doc, meta) { if (doc.type == 'landmark') { emit([doc.geo.lon, doc.geo.lat], null); } }",
                        Reduce: nil
                }
        }
}

// Insert design document into the bucket
bucketManager.InsertDesignDocument(designDoc)

When you want to update an existing document with a new view (or a modification of a view’s definition), you can use the upsertDesignDocument method.

However, this method needs the list of views in the document to be exhaustive, meaning that if you just create the new view definition as previously and add it to a new DesignDocument that you upsert, all your other views will be erased!

The solution is to perform a getDesignDocument, add your view definition to the DesignDocument’s views list, then upsert it. This also works with view modifications, provided the change is in the map or reduce functions (just reuse the same name for the modified View), or for deletion of one out of several views in the document.

//(note: obtaining the bucketManager is omitted in this snippet)
// Get design document to be updated
designDoc := bucketManager.GetDesignDocument("landmarks")

// Update the "by_country" view, adding a reduce
designDoc.Views["by_country"] := View { //reuse same name
        Map: "function (doc, meta) { if (doc.type == 'landmark') { emit([doc.country, doc.city], null); } }", //same map function
        Reduce: "_count" //added reduce function
}

// Resend to server
bucketManager.UpsertDesignDocument(designDoc)

To remove a design document from a bucket, pass its name to the RemoveDesignDocument method.