From e09f9825c828f841b52ffadd109db7a66ecba397 Mon Sep 17 00:00:00 2001 From: Maria Shodunke Date: Thu, 31 Mar 2022 16:13:06 +0100 Subject: [PATCH] Add scoped query index examples and doc --- .../howtos/examples/query-index-manager.go | 139 ++++++++++++++++++ .../pages/provisioning-cluster-resources.adoc | 116 ++++++++++++--- .../pages/sdk-user-management-example.adoc | 6 +- modules/test/test-howtos.bats | 27 ++-- 4 files changed, 250 insertions(+), 38 deletions(-) create mode 100644 modules/howtos/examples/query-index-manager.go diff --git a/modules/howtos/examples/query-index-manager.go b/modules/howtos/examples/query-index-manager.go new file mode 100644 index 00000000..768136af --- /dev/null +++ b/modules/howtos/examples/query-index-manager.go @@ -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[] +} diff --git a/modules/howtos/pages/provisioning-cluster-resources.adoc b/modules/howtos/pages/provisioning-cluster-resources.adoc index ff68af08..ffdf0464 100644 --- a/modules/howtos/pages/provisioning-cluster-resources.adoc +++ b/modules/howtos/pages/provisioning-cluster-resources.adoc @@ -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. @@ -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: @@ -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: @@ -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. @@ -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 -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: @@ -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. diff --git a/modules/howtos/pages/sdk-user-management-example.adoc b/modules/howtos/pages/sdk-user-management-example.adoc index 2e3daf64..02716a34 100644 --- a/modules/howtos/pages/sdk-user-management-example.adoc +++ b/modules/howtos/pages/sdk-user-management-example.adoc @@ -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 @@ -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 diff --git a/modules/test/test-howtos.bats b/modules/test/test-howtos.bats index b767486c..dff9abbf 100644 --- a/modules/test/test-howtos.bats +++ b/modules/test/test-howtos.bats @@ -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 \ + -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 +}