diff --git a/modules/howtos/examples/query_index_manager.py b/modules/howtos/examples/query_index_manager.py new file mode 100644 index 00000000..aa6b92b4 --- /dev/null +++ b/modules/howtos/examples/query_index_manager.py @@ -0,0 +1,100 @@ +from datetime import timedelta + +from couchbase.auth import PasswordAuthenticator +from couchbase.cluster import Cluster +from couchbase.exceptions import QueryIndexAlreadyExistsException +from couchbase.management.queries import (BuildDeferredQueryIndexOptions, + CreatePrimaryQueryIndexOptions, + CreateQueryIndexOptions, + DropPrimaryQueryIndexOptions, + DropQueryIndexOptions, + WatchQueryIndexOptions) + + +def primary_index(query_index_mgr): + print("Example - [primary]") + # tag::primary[] + try: + query_index_mgr.create_primary_index("travel-sample", CreatePrimaryQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users", + # Set this if you wish to use a custom name + # index_name="custom_name", + ignore_if_exists=True + )) + except QueryIndexAlreadyExistsException: + print("Index already exists") + # end::primary[] + + +def secondary_index(query_index_mgr): + print("Example - [secondary]") + # tag::secondary[] + try: + query_index_mgr.create_index("travel-sample", "tenant_agent_01_users_email", ["preferred_email"], CreateQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users" + )) + except QueryIndexAlreadyExistsException: + print("Index already exists") + # end::secondary[] + + +def defer_and_watch_index(query_index_mgr): + print("Example - [defer-indexes]") + # tag::defer-indexes[] + try: + # Create a deferred index + query_index_mgr.create_index("travel-sample", "tenant_agent_01_users_phone", ["preferred_phone"], CreateQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users", + deferred=True + )) + + # Build any deferred indexes within `travel-sample`.tenant_agent_01.users + query_index_mgr.build_deferred_indexes("travel-sample", BuildDeferredQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users" + )) + + # Wait for indexes to come online + query_index_mgr.watch_indexes("travel-sample", ["tenant_agent_01_users_phone"], WatchQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users", + timeout=timedelta(seconds=30) + )) + except QueryIndexAlreadyExistsException: + print("Index already exists") + # end::defer-indexes[] + + +def drop_primary_and_secondary_index(query_index_mgr): + print("Example - [drop-primary-or-secondary-index]") + # tag::drop-primary-or-secondary-index[] + # Drop a primary index + query_index_mgr.drop_primary_index("travel-sample", DropPrimaryQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users" + )) + + # Drop a secondary index + query_index_mgr.drop_index("travel-sample", "tenant_agent_01_users_email", DropQueryIndexOptions( + scope_name="tenant_agent_01", + collection_name="users" + )) + # end::drop-primary-or-secondary-index[] + + +# tag::creating-index-mgr[] +cluster = Cluster( + "couchbase://localhost", + authenticator=PasswordAuthenticator("Administrator", "password") +) + +query_index_mgr = cluster.query_indexes() +# end::creating-index-mgr[] + +primary_index(query_index_mgr) +secondary_index(query_index_mgr) +defer_and_watch_index(query_index_mgr) +drop_primary_and_secondary_index(query_index_mgr) diff --git a/modules/howtos/pages/provisioning-cluster-resources.adoc b/modules/howtos/pages/provisioning-cluster-resources.adoc index 9854d931..55aaaa79 100644 --- a/modules/howtos/pages/provisioning-cluster-resources.adoc +++ b/modules/howtos/pages/provisioning-cluster-resources.adoc @@ -2,6 +2,20 @@ :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[`upsert_design_document` method] +:getDesignDocument: pass:q[`get_design_document`] include::project-docs:partial$attributes.adoc[] @@ -15,18 +29,18 @@ The Python SDK also comes with some convenience functionality for common Couchba Management operations in the SDK may be performed through several interfaces depending on the object: -* BucketManager -- `Cluster.Buckets()` -* UserManager -- `Cluster.Users()` -* 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. +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. @@ -79,7 +93,7 @@ include::howtos:example$provisioning_resources_buckets.py[tag=drop_bucket] ---- [#python-flushing] -== Flushing Buckets +=== Flushing Buckets include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=flush-intro] @@ -105,8 +119,6 @@ for further details. include::howtos:example$provisioning_resources_collections.py[tag=create_collections_mgr] ---- -=== Creating and Deleting Scopes and Collections - You can create a scope: [source,python] @@ -141,8 +153,6 @@ You can create users with the appropriate RBAC programmatically: include::howtos:example$provisioning_resources_collections.py[tag=scopeAdmin] ---- -=== Listing the Scopes and Collections available - You can enumerate Scopes and Collections using the `CollectionManager.get_all_scopes()` method and the `Scope.collections` property. @@ -154,20 +164,72 @@ include::howtos:example$provisioning_resources_collections.py[tag=listing-scope- == 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.query_indexes()` method. + +[source,python] +---- +include::howtos:example$query_index_manager.py[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 `create_primary_index()` method. +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,python] +---- +include::howtos:example$query_index_manager.py[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 `index_name` property in the `CreatePrimaryQueryIndexOptions` class. -* QueryIndexManager -- https://docs.couchbase.com/sdk-api/couchbase-python-client/api/couchbase.html#n1ql-index-management[`Cluster.QueryIndexes()`]; -* AnalyticsIndexManager -- https://docs.couchbase.com/sdk-api/couchbase-python-client/api/couchbase.html[`Cluster.AnalyticsIndexes()`]; -* SearchIndexManager -- https://docs.couchbase.com/sdk-api/couchbase-python-client/api/couchbase.html[`Cluster.SearchIndexes()`]; -* ViewIndexManager -- https://docs.couchbase.com/sdk-api/couchbase-python-client/api/couchbase.html[`Bucket.ViewIndexes()`]. +You may have noticed that the example also sets the `ignore_if_exists` 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. +Creating a _secondary_ index follows a similar approach, with some minor differences: -// * Query +.Creating a secondary index + +[source,python] +---- +include::howtos:example$query_index_manager.py[tag=secondary,indent=0] +---- + +The `create_index()` method 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,python] +---- +include::howtos:example$query_index_manager.py[tag=defer-indexes,indent=0] +---- + +To delete a query index you can use the `drop_index()` or `drop_primary_index()` methods. +Which one you use depends on the type of query index you wish to drop from the database. + +.Deleting an index + +[source,python] +---- +include::howtos:example$query_index_manager.py[tag=drop-primary-or-secondary-index,indent=0] +---- // * Search - note & link to FTS page & API? -== View Management +== Views Management include::{version-server}@sdk:shared:partial$flush-info-pars.adoc[tag=view-management]