Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions modules/howtos/examples/query-index-manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package main

import (
"errors"
"fmt"
"time"

gocb "github.com/couchbase/gocb/v2"
)

func main() {
// tag::creating-index-mgr[]
cluster, err := gocb.Connect("localhost", gocb.ClusterOptions{
Authenticator: gocb.PasswordAuthenticator{
Username: "Administrator",
Password: "password",
},
})
if err != nil {
panic(err)
}

if err = cluster.WaitUntilReady(5*time.Second, nil); err != nil {
panic(err)
}

queryIndexMgr := cluster.QueryIndexes()
// end::creating-index-mgr[]

primaryIndex(queryIndexMgr)
secondaryIndex(queryIndexMgr)
deferAndWatchIndex(queryIndexMgr)
dropPrimaryAndSecondaryIndex(queryIndexMgr)
}

func primaryIndex(queryIndexMgr *gocb.QueryIndexManager) {
fmt.Println("Example - [primary]")
// tag::primary[]
if err := queryIndexMgr.CreatePrimaryIndex("travel-sample",
&gocb.CreatePrimaryQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
// Set this if you wish to use a custom name
// CustomName: "custom_name",
IgnoreIfExists: true,
},
); err != nil {
if errors.Is(err, gocb.ErrIndexExists) {
fmt.Println("Index already exists")
} else {
panic(err)
}
}
// end::primary[]
}

func secondaryIndex(queryIndexMgr *gocb.QueryIndexManager) {
fmt.Println("\nExample - [secondary]")
// tag::secondary[]
if err := queryIndexMgr.CreateIndex("travel-sample", "tenant_agent_01_users_email", []string{"preferred_email"},
&gocb.CreateQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
},
); err != nil {
if errors.Is(err, gocb.ErrIndexExists) {
fmt.Println("Index already exists")
} else {
panic(err)
}
}
// end::secondary[]
}

func deferAndWatchIndex(queryIndexMgr *gocb.QueryIndexManager) {
fmt.Println("\nExample - [defer-indexes]")
// tag::defer-indexes[]
// Create a deferred index
if err := queryIndexMgr.CreateIndex("travel-sample", "tenant_agent_01_users_phone", []string{"preferred_phone"},
&gocb.CreateQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
Deferred: true,
},
); err != nil {
if errors.Is(err, gocb.ErrIndexExists) {
fmt.Println("Index already exists")
} else {
panic(err)
}
}

// Build any deferred indexes within `travel-sample`.tenant_agent_01.users
indexesToBuild, err := queryIndexMgr.BuildDeferredIndexes("travel-sample",
&gocb.BuildDeferredQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
},
)
if err != nil {
panic(err)
}

// Wait for indexes to come online
if err = queryIndexMgr.WatchIndexes("travel-sample", indexesToBuild, time.Duration(30*time.Second),
&gocb.WatchQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
},
); err != nil {
panic(err)
}
// end::defer-indexes[]
}

func dropPrimaryAndSecondaryIndex(queryIndexMgr *gocb.QueryIndexManager) {
fmt.Println("\nExample - [drop-primary-or-secondary-index]")
// tag::drop-primary-or-secondary-index[]
// Drop a primary index
if err := queryIndexMgr.DropPrimaryIndex("travel-sample",
&gocb.DropPrimaryQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
},
); err != nil {
panic(err)
}

// Drop a secondary index
if err := queryIndexMgr.DropIndex("travel-sample", "tenant_agent_01_users_email",
&gocb.DropQueryIndexOptions{
ScopeName: "tenant_agent_01",
CollectionName: "users",
},
); err != nil {
panic(err)
}
// end::drop-primary-or-secondary-index[]
}
116 changes: 92 additions & 24 deletions modules/howtos/pages/provisioning-cluster-resources.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,45 @@
:description: Provisioning cluster resources is managed at the collection or bucket level, depending upon the service affected.
:navtitle: Provisioning Cluster Resources
:page-aliases: ROOT:managing-clusters
:page-toclevels: 2

// API refs
:bucket-api-reference: pass:q[BucketManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.Buckets[`Cluster.Buckets()`]]
:user-api-reference: pass:q[UserManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.Users[`Cluster.Users()`]]
:query-api-reference: pass:q[QueryIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.QueryIndexes[`Cluster.QueryIndexes()`]]
:analytics-api-reference: pass:q[AnalyticsIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.AnalyticsIndexes[`Cluster.AnalyticsIndexes()`]]
:search-api-reference: pass:q[SearchIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.SearchIndexes[`Cluster.SearchIndexes()`]]
:collection-api-reference: pass:q[CollectionManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Bucket.Collections[`Bucket.Collections()`]]
:view-api-reference: pass:q[ ViewIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Bucket.ViewIndexes[`Bucket.ViewIndexes()`]]

// one-view-update-warning common partial
:upsertDesignDocument: pass:q[`UpsertDesignDocument` method]
:getDesignDocument: pass:q[`GetDesignDocument`]

include::project-docs:partial$attributes.adoc[]

[abstract]
{description}
Common use cases are outlined here, less common use cases are covered in the https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc[API docs].

include::7.0@sdk:shared:partial$flush-info-pars.adoc[tag=management-intro]
include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=management-intro]

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

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

* BucketManager -- `Cluster.Buckets()`
* UserManager -- `Cluster.Users()`
// see xref
* QueryIndexManager -- `Cluster.QueryIndexes()`
* AnalyticsIndexManager -- `Cluster.AnalyticsIndexes()`
* SearchIndexManager -- `Cluster.SearchIndexes()`
* CollectionManager -- `Bucket.Collections()`
* ViewIndexManager -- `Bucket.ViewIndexes()`.
* {bucket-api-reference}
* {user-api-reference}
* {query-api-reference}
* {analytics-api-reference}
* {search-api-reference}
* {collection-api-reference}
* {view-api-reference}

NOTE: When using a Couchbase version earlier than 6.5, you must create a valid Bucket connection using `cluster.Bucket(name)` before you can use cluster level managers.


== Creating and Removing Buckets
== Bucket Management

The `BucketManager` interface may be used to create and delete buckets from the Couchbase cluster.
It is instantiated through the `Cluster.Buckets()` method.
Expand All @@ -37,7 +52,7 @@ include::devguide:example$go/provisioning-resources-buckets.go[tag=creatingbucke

The `CreateBucketSettings` and `BucketSettings` structs are used for creating and updating buckets, `BucketSettings` is also used for exposing information about existing buckets.

include::7.0@sdk:shared:partial$flush-info-pars.adoc[tag=update-bucket-warning]
include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=update-bucket-warning]

Here is the list of parameters available:

Expand Down Expand Up @@ -77,9 +92,9 @@ include::devguide:example$go/provisioning-resources-buckets.go[tag=removeBucket]
----

[#go-flushing]
== Flushing Buckets
=== Flushing Buckets

include::7.0@sdk:shared:partial$flush-info-pars.adoc[tag=flush-intro]
include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=flush-intro]

You can flush a bucket in the SDK by using the `Flush` method:

Expand All @@ -92,7 +107,7 @@ The `Flush` operation may fail if the bucket does not have flush enabled, in tha

== Collection Management

The CollectionManager interface may be used to create and delete scopes and collections from the Couchbase cluster.
The `CollectionManager` interface may be used to create and delete scopes and collections from the Couchbase cluster.
It is instantiated through the `Bucket.Collections()` method.
Refer to the https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Bucket.Collections[`CollectionManager` API documentation]
for further details.
Expand Down Expand Up @@ -141,21 +156,74 @@ include::example$collection-manager.go[tag=scopeAdmin, indent=0]

== Index Management

In general, you will rarely need to work with Index Managers from the SDK.
For those occasions when you do, please see the relevant API docs:
include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=index-management-intro]

=== QueryIndexManager

The `QueryIndexManager` interface contains the means for managing indexes used for queries.
It can be instantiated through the `Cluster.QueryIndexes()` method.

[source,golang]
----
include::example$query-index-manager.go[tag=creating-index-mgr,indent=0]
----

include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=query-index-manager-intro]

The example below shows how to create a simple primary index, restricted to a named scope and collection, by calling the `CreatePrimaryIndex()` function.
Note that you cannot provide a named scope or collection separately, both must be set for the `QueryIndexManager` to create an index on the relevant keyspace path.

.Creating a primary index

[source,golang]
----
include::example$query-index-manager.go[tag=primary,indent=0]
----

When a primary index name is not specified, the SDK will create the index as `#primary` by default.
However, if you wish to provide a custom name, you can simply set a `CustomName` property in the `CreatePrimaryQueryIndexOptions` struct.

You may have noticed that the example also sets the `IgnoreIfExists` boolean flag.
When set to `true`, this optional argument ensures that an error is not thrown if an index under the same name already exists.

* QueryIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.QueryIndexes[`Cluster.QueryIndexes()`];
* AnalyticsIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.AnalyticsIndexes[`Cluster.AnalyticsIndexes()`];
* SearchIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Cluster.SearchIndexes[`Cluster.SearchIndexes()`];
* ViewIndexManager -- https://pkg.go.dev/github.com/couchbase/gocb/v2?tab=doc#Bucket.ViewIndexes[`Bucket.ViewIndexes()`].
Creating a _secondary_ index follows a similar approach, with some minor differences:

// * Query
.Creating a secondary index

[source,golang]
----
include::example$query-index-manager.go[tag=secondary,indent=0]
----

The `CreateIndex()` function requires an index name to be provided, along with the fields to create the index on.
Like the _primary_ index, you can restrict a _secondary_ index to a named scope and collection by passing some options.

Indexes can easily take a long time to build if they contain a lot of documents.
In these situations, it is more ideal to build indexes in the background.
To achieve this we can use the `Deferred` boolean option, and set it to `true`.

.Deferring index creation

[source,golang]
----
include::example$query-index-manager.go[tag=defer-indexes,indent=0]
----

To delete a query index you can use the `DropIndex()` or `DropPrimaryIndex()` functions.
Which one you use depends on the type of query index you wish to drop from the database.

.Deleting an index

[source,golang]
----
include::example$query-index-manager.go[tag=drop-primary-or-secondary-index,indent=0]
----

// * Search - note & link to FTS page & API?

== View Management
== Views Management
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, why is this plural btw? We don't say "Indexes management" for example.

Oh, is it because of ambiguity of "View" (verb/noun)? Hmm. OK, still, seems a bit inconsistent, only just noticed this time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Views is short for Map/Reduce Views.


include::7.0@sdk:shared:partial$flush-info-pars.adoc[tag=view-management]
include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=view-management]

In the SDK, design documents are represented by the `DesignDocument` and `View` structs.
All operations on design documents are performed on the `ViewIndexManager` instance:
Expand All @@ -172,7 +240,7 @@ The following example upserts a design document with two views:
include::devguide:example$go/provisioning-resources-views.go[tag=createView]
----

include::7.0@sdk:shared:partial$flush-info-pars.adoc[tag=one-view-update-warning]
include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=one-view-update-warning]

Note the use of `DesignDocumentNamespaceDevelopment`, the other option is `DesignDocumentNamespaceProduction`.
This parameter specifies whether the design document should be created as development, or as production -- with the former running over only a small fraction of the documents.
Expand Down
6 changes: 3 additions & 3 deletions modules/howtos/pages/sdk-user-management-example.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
= User Management
:description: pass:q[The Java SDK lets you create _users_, assign them _roles_ and associated _privileges_, and remove them from the system.]
:description: pass:q[The Go SDK lets you create _users_, assign them _roles_ and associated _privileges_, and remove them from the system.]
:navtitle: Provisioning Cluster Resources
:page-aliases: ROOT:sdk-user-management-example.adoc

Expand All @@ -9,9 +9,9 @@
== User-Management APIs

Users who have been assigned the *Admin* role for the cluster are able to create, edit, and remove users.
The Java SDK provides APIs to support these activities.
The Go SDK provides APIs to support these activities.
A high-level summary of the APIs can be found in xref:concept-docs:sdk-user-management-overview.adoc[User-Management],
and details of all options in the https://docs.couchbase.com/sdk-api/couchbase-java-client/com/couchbase/client/java/manager/user/UserManager.html[UserManager API docs].
and details of all options in the https://pkg.go.dev/github.com/couchbase/gocb/v2#UserManager[UserManager API docs].

== Using the UserManager API

Expand Down
27 changes: 16 additions & 11 deletions modules/test/test-howtos.bats
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,32 @@ load 'test_helper'
}

@test "[howtos] - query.go" {
runExample $HOWTOS_DIR query.go
assert_success
assert_output --partial "map[greeting:hello]"
runExample $HOWTOS_DIR query.go
assert_success
assert_output --partial "map[greeting:hello]"
}

@test "[howtos] - collection-manager.go" {
runExample $HOWTOS_DIR collection-manager.go
assert_success
assert_output --partial "drop-scope"
runExample $HOWTOS_DIR collection-manager.go
assert_success
assert_output --partial "drop-scope"
}

@test "[howtos] - subdoc.go" {
echo "create example document"
cbimport json --verbose \
-c localhost -u Administrator -p password \
-b travel-sample \
-f lines \
-d file:///modules/test/fixtures/customer123.json \
-g customer123
-c localhost -u Administrator -p password \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woot! your shell plugin has started doing indentation correctly! 👍 😉

-b travel-sample \
-f lines \
-d file:///modules/test/fixtures/customer123.json \
-g customer123
echo

runExample $HOWTOS_DIR subdoc.go
assert_success
}

@test "[howtos] - query-index-manager.go" {
runExample $HOWTOS_DIR query-index-manager.go
assert_success
}