From 6673ae836050737896c55bab2b370a0bd0ca7538 Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Thu, 12 Jun 2025 09:29:47 +0530 Subject: [PATCH 01/14] [DOC-10909] Add 'Errors' Logging Qualifier (#365) --- modules/n1ql/pages/n1ql-manage/monitoring-n1ql-query.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/n1ql/pages/n1ql-manage/monitoring-n1ql-query.adoc b/modules/n1ql/pages/n1ql-manage/monitoring-n1ql-query.adoc index e2ff97e69..5f14013e7 100644 --- a/modules/n1ql/pages/n1ql-manage/monitoring-n1ql-query.adoc +++ b/modules/n1ql/pages/n1ql-manage/monitoring-n1ql-query.adoc @@ -731,6 +731,7 @@ A completed request is logged if _any_ of the qualifiers are met (logical OR). `context`:: Log requests with this client context ID. `statement`:: Log requests that match the specified LIKE search pattern in the query text. `plan`:: Log requests where the specified plan field values appear in the query plan. +`errors`:: Log requests with at least this many errors. For full details, see xref:n1ql-rest-admin:index.adoc#Logging_Parameters[Logging Parameters]. From 578ea446ab4db6b11855789c331ab901cfec8340 Mon Sep 17 00:00:00 2001 From: sarahlwelton <110928505+sarahlwelton@users.noreply.github.com> Date: Thu, 12 Jun 2025 11:45:57 -0400 Subject: [PATCH 02/14] [DOC-13303] FTS - Create Search Index Alias with REST API (#364) * [DOC-13303] Initial commit of index alias REST API creation topics * [DOC-13303] Clarify language * [DOC-13303] Tweak guidance around permissions for searches to be more clear * [DOC-13303] Tweaking based on peer review --- .../create-search-alias-header-global.sh | 3 + .../create-search-alias-header-scoped.sh | 3 + .../create-search-alias-payload-global.sh | 19 +++ .../create-search-alias-payload-scoped.sh | 20 +++ .../create-search-alias-response-global.json | 5 + .../create-search-alias-response-scoped.json | 5 + .../create-search-alias-targets-example.json | 7 ++ .../create-search-index-alias-rest-api.adoc | 114 ++++++++++++++++++ modules/search/pages/index-aliases.adoc | 3 +- modules/search/pages/search-index-params.adoc | 66 ++++++++-- .../search/pages/simple-search-rest-api.adoc | 2 +- modules/search/pages/simple-search-ui.adoc | 2 +- modules/search/partials/nav.adoc | 1 + 13 files changed, 237 insertions(+), 13 deletions(-) create mode 100644 modules/search/examples/create-search-alias-header-global.sh create mode 100644 modules/search/examples/create-search-alias-header-scoped.sh create mode 100644 modules/search/examples/create-search-alias-payload-global.sh create mode 100644 modules/search/examples/create-search-alias-payload-scoped.sh create mode 100644 modules/search/examples/create-search-alias-response-global.json create mode 100644 modules/search/examples/create-search-alias-response-scoped.json create mode 100644 modules/search/examples/create-search-alias-targets-example.json create mode 100644 modules/search/pages/create-search-index-alias-rest-api.adoc diff --git a/modules/search/examples/create-search-alias-header-global.sh b/modules/search/examples/create-search-alias-header-global.sh new file mode 100644 index 000000000..c4675aa84 --- /dev/null +++ b/modules/search/examples/create-search-alias-header-global.sh @@ -0,0 +1,3 @@ +curl -s -XPUT -H "Content-Type: application/json" \ + -u ${CB_USERNAME}:${CB_PASSWORD} http://${CB_HOSTNAME}:8094/api/index/${INDEX_NAME} + -d \ \ No newline at end of file diff --git a/modules/search/examples/create-search-alias-header-scoped.sh b/modules/search/examples/create-search-alias-header-scoped.sh new file mode 100644 index 000000000..6e617764e --- /dev/null +++ b/modules/search/examples/create-search-alias-header-scoped.sh @@ -0,0 +1,3 @@ +curl -s -XPUT -H "Content-Type: application/json" \ + -u ${CB_USERNAME}:${CB_PASSWORD} http://${CB_HOSTNAME}:8094/api/bucket/${BUCKET_NAME}/scope/${SCOPE_NAME}/index/${INDEX_NAME} + -d \ \ No newline at end of file diff --git a/modules/search/examples/create-search-alias-payload-global.sh b/modules/search/examples/create-search-alias-payload-global.sh new file mode 100644 index 000000000..7d9006fb3 --- /dev/null +++ b/modules/search/examples/create-search-alias-payload-global.sh @@ -0,0 +1,19 @@ +curl -s -XPUT -H "Content-Type: application/json" \ + -u ${CB_USERNAME}:${CB_PASSWORD} http://localhost:8094/api/index/travel-color-alias + -d \ + '{ + "name": "travel-sample-alias", + "type": "fulltext-alias", + "params": { + "targets": { + "travel-sample.inventory.landmark-content": {}, + "vector-sample.color.color-index": {} + } + }, + "sourceType": "nil", + "sourceName": "", + "sourceUUID": "", + "sourceParams": null, + "planParams": {}, + "uuid": "" + }' \ No newline at end of file diff --git a/modules/search/examples/create-search-alias-payload-scoped.sh b/modules/search/examples/create-search-alias-payload-scoped.sh new file mode 100644 index 000000000..a0ec8ee20 --- /dev/null +++ b/modules/search/examples/create-search-alias-payload-scoped.sh @@ -0,0 +1,20 @@ +curl -s -XPUT -H "Content-Type: application/json" \ + -u ${CB_USERNAME}:${CB_PASSWORD} http://localhost:8094/api/bucket/travel-sample/scope/inventory/index/travel-sample-alias + -d \ + '{ + "name": "travel-sample-alias", + "type": "fulltext-alias", + "params": { + "targets": { + "travel-sample.inventory.landmark-content": {}, + "travel-sample.inventory.hotel-reviews": {}, + "travel-sample.inventory.routes": {} + } + }, + "sourceType": "nil", + "sourceName": "", + "sourceUUID": "", + "sourceParams": null, + "planParams": {}, + "uuid": "" + }' \ No newline at end of file diff --git a/modules/search/examples/create-search-alias-response-global.json b/modules/search/examples/create-search-alias-response-global.json new file mode 100644 index 000000000..c0a7f9ce1 --- /dev/null +++ b/modules/search/examples/create-search-alias-response-global.json @@ -0,0 +1,5 @@ +{ + "status": "ok", + "name": "travel-color-alias", + "uuid": "d630f5570437ff92" +} \ No newline at end of file diff --git a/modules/search/examples/create-search-alias-response-scoped.json b/modules/search/examples/create-search-alias-response-scoped.json new file mode 100644 index 000000000..05530a2c6 --- /dev/null +++ b/modules/search/examples/create-search-alias-response-scoped.json @@ -0,0 +1,5 @@ +{ + "status": "ok", + "name": "travel-sample.inventory.travel-sample-alias", + "uuid": "7e569bdb5d3a2a83" +} \ No newline at end of file diff --git a/modules/search/examples/create-search-alias-targets-example.json b/modules/search/examples/create-search-alias-targets-example.json new file mode 100644 index 000000000..580601b0f --- /dev/null +++ b/modules/search/examples/create-search-alias-targets-example.json @@ -0,0 +1,7 @@ +"params": { + "targets": { + "travel-sample.inventory.landmark-content": {}, + "travel-sample.inventory.hotel-reviews": {}, + "travel-sample.inventory.routes": {} + } + }, \ No newline at end of file diff --git a/modules/search/pages/create-search-index-alias-rest-api.adoc b/modules/search/pages/create-search-index-alias-rest-api.adoc new file mode 100644 index 000000000..1fdacbdb3 --- /dev/null +++ b/modules/search/pages/create-search-index-alias-rest-api.adoc @@ -0,0 +1,114 @@ += Create a Search Index Alias with the REST API +:page-topic-type: guide +:page-ui-name: {ui-name} +:page-product-name: {product-name} +:description: Use the REST API to create a Search index alias. Use a Search index alias to run a Search query across multiple buckets, scopes, or Search indexes. + +[abstract] +{description} + +== Prerequisites + +* You have the Search Service enabled on a node in your cluster. +For more information about how to deploy a new node and Services on your cluster, see xref:server:manage:manage-nodes/node-management-overview.adoc[]. + +* You have created at least one Search index. +For more information, see xref:create-search-index-ui.adoc[] or xref:create-search-index-rest-api.adoc[]. + +* Your user account has the *Search Admin* role for the bucket where you want to create the alias. + +* You have installed the Couchbase command-line tool (CLI). + +* You have the hostname or IP address for the node in your cluster where you're running the Search Service. +For more information about where to find the IP address for your node, see xref:server:manage:manage-nodes/list-cluster-nodes.adoc[]. + +== Procedure + +To create a Search index alias with the REST API: + +. In your command-line tool, enter a `curl` command with the `XPUT` verb. +. Set your header content to include `"Content-Type: application/json"`. +. Enter your username, password, and the Search Service endpoint on port `8094` with the name of the index you want to create. ++ +If your alias's target Search indexes are all in the same bucket and scope, use the scoped index creation endpoint: ++ +.Scoped Index Creation Endpoint +[source,console] +---- +include::example$create-search-alias-header-scoped.sh[] +---- ++ +If your target Search indexes are in different buckets or scopes, use the global index creation endpoint: ++ +.Global Index Creation Endpoint +[source,console] +---- +include::example$create-search-alias-header-global.sh[] +---- ++ +To use SSL, use the `https` protocol in the Search Service endpoint URL and port `18094`. ++ +[NOTE] +==== +Your alias name must start with an alphabetic character (a-z or A-Z). It can only contain alphanumeric characters (a-z, A-Z, or 0-9), hyphens (-), or underscores (_). + +For Couchbase Server version 7.6 and later, if you're using the scoped endpoint, your alias name must be unique inside your selected bucket and scope. +You cannot have 2 aliases with the same name globally or inside the same bucket and scope. +==== + +. Enter the JSON payload for your Search index alias. +Your Search index alias only requires the properties from xref:search-index-params.adoc#initial[the start of a Search index JSON payload], except where otherwise noted. + +== Example: Create an Alias With Targets in the Same Bucket and Scope + +In the following example, the JSON payload creates an index alias named `travel-sample-alias`, which contains the `landmark-content`, `hotel-reviews`, and `routes` Search indexes: + +[source,console] +---- +include::example$create-search-alias-payload-scoped.sh[] +---- + +All the Search indexes in the `targets` object are in the same bucket and scope, so the REST API call uses the scoped endpoint to create a scoped alias. + +If the REST API call is successful, the Search Service returns a `200 OK` and the following JSON response: + +[source,json] +---- +include::example$create-search-alias-response-scoped.json[] +---- + +The `"uuid"` is randomly generated for each Search index alias you create. +Your own UUID might not match the value shown in the example. + +== Example: Create an Alias With Targets in Different Buckets + +In the following example, the JSON payload creates an index alias named `travel-color-alias`, which contains the `landmark-content` and `color-index` Search indexes, which are in different buckets on the cluster: + +[source,console] +---- +include::example$create-search-alias-payload-global.sh[] +---- + +The REST API call uses the global endpoint to create a global alias. + +If the REST API call is successful, the Search Service returns a `200 OK` and the following JSON response: + +[source,json] +---- +include::example$create-search-alias-response-global.json[] +---- + +The `"uuid"` is randomly generated for each Search index alias you create. +Your own UUID might not match the value shown in the example. + +== Next Steps + +After you create a Search index alias, you can xref:simple-search-rest-api.adoc[] to test your alias and Search indexes. + +If you want to edit your alias with another REST API call, include the xref:search-index-params.adoc#uuid[uuid] parameter with your alias UUID. + +You can get the UUID from the response to your first call. +You can also view the UUID from the Couchbase {page-ui-name} by selecting the alias, and clicking btn:[Edit Index]. +The UUID displays in the Index Definition Preview on the Edit Index page. + +You can also use the xref:rest-api:rest-fts-indexing.adoc[Index Definition] endpoints provided by the Search REST API. \ No newline at end of file diff --git a/modules/search/pages/index-aliases.adoc b/modules/search/pages/index-aliases.adoc index fc079a6c9..b6eb744d6 100644 --- a/modules/search/pages/index-aliases.adoc +++ b/modules/search/pages/index-aliases.adoc @@ -20,10 +20,11 @@ If you created a clone of `old-index`, then made your updates, you could replace Using a Search index alias lets you edit `old-index` without any downtime. -For more information about how to create a Search index alias, see xref:create-search-index-alias.adoc[]. +For more information about how to create a Search index alias, see xref:create-search-index-alias.adoc[] or xref:create-search-index-alias-rest-api.adoc[]. == See Also * xref:create-search-index-alias.adoc[] +* xref:create-search-index-alias-rest-api.adoc[] * xref:import-search-index.adoc[] diff --git a/modules/search/pages/search-index-params.adoc b/modules/search/pages/search-index-params.adoc index dd0635632..1bb7a1e2a 100644 --- a/modules/search/pages/search-index-params.adoc +++ b/modules/search/pages/search-index-params.adoc @@ -27,13 +27,24 @@ include::example$simple-search-index-payload.jsonc[tag=json-snippet] TIP: To view the entire JSON payload, click btn:[View]. +When you xref:create-search-index-alias-rest-api.adoc[], the properties in this section are the only properties you need to include in your alias definition. + All Search index payloads have the following properties: [cols="1,1,1,2"] |==== |Property |Type |Required? |Description -|name |String |Yes |The name of the Search index. A Search index name must be unique for each cluster. +|name |String |Yes a| + +The name of the Search index or index alias. + +For Couchbase Server version 7.6 and later, your index name must be unique inside your selected bucket and scope. +You cannot have 2 indexes with the same name inside the same bucket and scope. + +For index aliases, names must be unique within the same bucket and scope if you're using the scoped endpoint. +Global index aliases must not share a name with another alias. +For more information about Search index aliases, see xref:index-aliases.adoc[]. |type |String |Yes a| @@ -41,25 +52,33 @@ The type of index you want to create: * `fulltext-index`: Create a Search index. * `fulltext-alias`: Create an alias for a Search index. -For more information about Search index aliases, see xref:index-aliases.adoc[]. +For more information about creating Search index aliases, see xref:create-search-index-alias-rest-api.adoc[]. |[[uuid]]uuid |String |No a| -The UUID for the Search index. +The UUID for the Search index or index alias. -The Search Service automatically generates a UUID for a Search index. +The Search Service automatically generates a UUID for a Search index or index alias. -If you use an existing UUID, the Search Service updates the existing Search index. -Do not include the `uuid` property when you want to copy an index to a different cluster or create a new index. +If you use an existing UUID, the Search Service updates the existing Search index or index alias. +Do not include the `uuid` property when you want to copy an index to a different cluster or create a new index or alias. View the UUID for an existing index from the Couchbase {page-ui-name} by selecting an existing index, and clicking btn:[Edit Index]. The UUID displays in the Index Definition Preview on the Edit Index page. You can also use the xref:rest-api:rest-fts-indexing.adoc[Index Definition] endpoints provided by the Search REST API. -|sourceType |String |Yes |The `sourceType` is always `"gocbcore"`. +|sourceType |String |Yes a| + +When you create a Search index, the `sourceType` is always `"gocbcore"`. -|sourceName |String |Yes |The name of the bucket where you want to create the Search index. +When you create an index alias, the `sourceType` is always `"nil"`. + +|sourceName |String |Yes a| + +The name of the bucket where you want to create the Search index. + +You do not need to include a value for this parameter when creating an index alias. |[[sourceuuid]]sourceUUID |String |No a| @@ -69,16 +88,27 @@ The Search Service automatically finds the UUID for the bucket. Do not include the `sourceUUID` property when you want to copy an index to a different cluster, or create a new index. +You do not need to include a value for this parameter when creating an index alias. + |sourceParams |Object |No a| This object contains advanced settings for index behavior. Do not add content into this object unless instructed by Couchbase Support. -|planParams |Object |Yes |An object that sets the Search index's partitions and replications. +|planParams |Object |Yes a| + +An object that sets the Search index's partitions and replications. For more information, see <>. -|params |Object |Yes |An object that sets the Search index's type identifier, type mappings, and analyzers. +For an index alias, set this to an empty object. + +|params |Object |Yes a| + +An object that sets the Search index's type identifier, type mappings, and analyzers. + +For an index alias, this sets the target Search indexes to include in the alias. + For more information, see <>. |store |Object |No a| @@ -144,6 +174,22 @@ For more information, see <>. |mapping |Object |Yes |An object that sets the analyzers and type mappings for a Search index. For more information, see <>. +|targets |Object |Index Alias Only a| + +When creating an index alias, an object that lists each Search index you want to include in the alias. + +The `targets` object should include a named object for each Search index you want to include in the alias. +Make sure to use the scoped index name for each Search index. + +For example: + +[source,json] +---- +include::example$create-search-alias-targets-example.json[] +---- + +For more information about creating aliases, see xref:create-search-index-alias.adoc[] or xref:create-search-index-alias-rest-api.adoc[]. + |==== [#doc-config] diff --git a/modules/search/pages/simple-search-rest-api.adoc b/modules/search/pages/simple-search-rest-api.adoc index cff23762c..fa89cc964 100644 --- a/modules/search/pages/simple-search-rest-api.adoc +++ b/modules/search/pages/simple-search-rest-api.adoc @@ -15,7 +15,7 @@ For more information about how the Search Service scores documents in search res * You have the Search Service enabled on a node in your cluster. For more information about how to deploy a new node and Services on your cluster, see xref:server:manage:manage-nodes/node-management-overview.adoc[]. -* Your user account has the xref:learn:security/roles.adoc#search-admin[`Search Admin`] or xref:learn:security/roles.adoc#search-reader[`Search Reader`] role. +* Your user account has the xref:learn:security/roles.adoc#search-admin[`Search Admin`] or xref:learn:security/roles.adoc#search-reader[`Search Reader`] role for the bucket or buckets that contain the Search indexes you want to search. * You installed the Couchbase command-line tool (CLI). diff --git a/modules/search/pages/simple-search-ui.adoc b/modules/search/pages/simple-search-ui.adoc index f7263e075..d7cc93333 100644 --- a/modules/search/pages/simple-search-ui.adoc +++ b/modules/search/pages/simple-search-ui.adoc @@ -22,7 +22,7 @@ For more information about how to create a bucket, see xref:server:manage:manage + For more information about how to create a Search index, see xref:create-search-indexes.adoc[]. -* Your user account has the xref:learn:security/roles.adoc#search-admin[`Search Admin`] or xref:learn:security/roles.adoc#search-reader[`Search Reader`] role. +* Your user account has the xref:learn:security/roles.adoc#search-admin[`Search Admin`] or xref:learn:security/roles.adoc#search-reader[`Search Reader`] role for the bucket or buckets that contain the Search indexes you want to search. * You have logged in to the Couchbase {page-ui-name}. diff --git a/modules/search/partials/nav.adoc b/modules/search/partials/nav.adoc index d3ca2a51c..5573ffeab 100644 --- a/modules/search/partials/nav.adoc +++ b/modules/search/partials/nav.adoc @@ -24,6 +24,7 @@ *** xref:8.0@server:search:search-query-auto-complete-code.adoc[] ** xref:8.0@server:search:index-aliases.adoc[] *** xref:8.0@server:search:create-search-index-alias.adoc[] + *** xref:8.0@server:search:create-search-index-alias-rest-api.adoc[] ** xref:8.0@server:search:customize-index.adoc[] *** xref:8.0@server:search:set-type-identifier.adoc[] *** xref:8.0@server:search:create-type-mapping.adoc[] From 4e8135ad9959a00e88e3c8ab4106ab5fcfd2beb3 Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Fri, 20 Jun 2025 18:59:58 +0530 Subject: [PATCH 03/14] [DOC-10618] Additional Date Formats (#368) --- .../n1ql-language-reference/datefun.adoc | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/modules/n1ql/pages/n1ql-language-reference/datefun.adoc b/modules/n1ql/pages/n1ql-language-reference/datefun.adoc index 7a0662641..a7f719955 100644 --- a/modules/n1ql/pages/n1ql-language-reference/datefun.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/datefun.adoc @@ -504,6 +504,72 @@ The elements are given in the table below. | Seconds since 1970-01-01 00:00:00 UTC | `1624904579` +| `x` +| Same as `%D` +| `2021-06-28` + +| `r` +| 12-hour time, hh:mm:ss AM/PM +| `07:22:59 AM` + +| `X` +| Same as `%T` +| `19:22:59` + +| `:z` +| UTC offset in the format, +HH:MM +| `+05:30` + +| `::z` +| UTC offset in the format, +HH:MM:SS +| `+05:30:00` + +| `:::z` +| UTC offset with minimum precision as required for the time zone +| `+05:30` or `+05:30:00` + +| `V` +| ISO week number +| `27` + +| `G` +| Year corresponding to the ISO week number +| `2025` + +| `j` +| Day of the year +| `179` + +| `q` +| Quarter of the year, 1-4 +| `2` + +| `w` +| Day of the week (Sunday=0) +| `1` + +| `u` +| Day of the week (Monday=1, Sunday=7) +| `2` + + +| `U` +| Week number of year (Sunday is first day of the week) +| `27` + +| `W` +| Week number of year (Monday is first day of the week) +| `27` + +| `#` +| Time since Epoch in the format, [total hours]:mm:ss +| `406464:27:15` + + +| `@` +| Time since Epoch in the format, [total hours]:mm:ss.fff +| `406464:27:15.123` + |==== To specify a date format, you can put the format specifiers together in any order, along with any other characters as required. From 1ed42e1f57db2629133c0a35af5e1d3ab7d3a0a4 Mon Sep 17 00:00:00 2001 From: Ray Offiah <77050471+RayOffiah@users.noreply.github.com> Date: Wed, 25 Jun 2025 16:09:44 +0100 Subject: [PATCH 04/14] [DOC-13308]: adocs ISSUES on Defer Indexes | Couchbase Docs (#369) Fixed broken links for Java and Python examples. --- modules/guides/pages/defer-index.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/guides/pages/defer-index.adoc b/modules/guides/pages/defer-index.adoc index d1fcb63e0..c564531c0 100644 --- a/modules/guides/pages/defer-index.adoc +++ b/modules/guides/pages/defer-index.adoc @@ -109,12 +109,12 @@ The following examples create a set of primary and secondary indexes in the spec [source,java] ---- -include::java-sdk:hello-world:example$IndexHelloWorld.java[tag=defer-create-primary,indent=0] +include::java-sdk:devguide:example$java/IndexHelloWorld.java[tag=defer-create-primary,indent=0] ---- [source,java] ---- -include::java-sdk:hello-world:example$IndexHelloWorld.java[tag=defer-create-secondary,indent=0] +include::java-sdk:devguide:example$java/IndexHelloWorld.java[tag=defer-create-secondary,indent=0] ---- {github} @@ -165,12 +165,12 @@ The following examples create a set of primary and secondary indexes in the spec [source,python] ---- -include::python-sdk:devguide:example$python/index_hello_world.py[tag=defer-create-primary,indent=0] +include::python-sdk:hello-world:example$index_hello_world.py[tag=defer-create-primary,indent=0] ---- [source,python] ---- -include::python-sdk:devguide:example$python/index_hello_world.py[tag=defer-create-secondary,indent=0] +include::python-sdk:hello-world:example$index_hello_world.py[tag=defer-create-secondary,indent=0] ---- {github} @@ -251,7 +251,7 @@ The following example builds all deferred indexes in the specified keyspace. [source,java] ---- -include::java-sdk:hello-world:example$IndexHelloWorld.java[tag=defer-build,indent=0] +include::java-sdk:devguide:example$java/IndexHelloWorld.java[tag=defer-build,indent=0] ---- {github} @@ -289,7 +289,7 @@ The following example builds all deferred indexes in the specified keyspace. [source,python] ---- -include::python-sdk:devguide:example$python/index_hello_world.py[tag=defer-build,indent=0] +include::python-sdk:hello-world:example$index_hello_world.py[tag=defer-build,indent=0] ---- {github} From fa5c22f52e0a9f895ac8651ff6bc857553a78087 Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Wed, 30 Jul 2025 15:30:31 +0530 Subject: [PATCH 05/14] [DOC-11152] Changes to date functions (#383) --- .../n1ql-language-reference/datefun.adoc | 104 ++++++++++++++---- 1 file changed, 85 insertions(+), 19 deletions(-) diff --git a/modules/n1ql/pages/n1ql-language-reference/datefun.adoc b/modules/n1ql/pages/n1ql-language-reference/datefun.adoc index a7f719955..39a7f1e7f 100644 --- a/modules/n1ql/pages/n1ql-language-reference/datefun.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/datefun.adoc @@ -588,13 +588,23 @@ If the date string does not explicitly declare the value of a component, then th * The month and day default to 1. * The century (when not specified by year) defaults to 19 if year is greater than or equal to 69, or 20 otherwise. * All other numeric components default to 0. -* The time zone defaults to the local local system time zone. +* The time zone defaults to the local system time zone. In cases where the timezone is not specified, the local system time is assumed. For example, `2016-02-07` is equivalent to `2016-02-07T00:00:00` and parsing just `16` as the year is equivalent to `2016-01-01T00:00:00` in the local system time zone. ==== +[NOTE#tzn-date-format] +.TZN Date Format +==== +In addition to the date formats listed <>, {sqlpp} also supports the `TZN` (Time Zone Name) format. +This format parses date strings in the same way as `TZD` but outputs the time zone name instead of the offset. +For example, the `TZN` representation of the "Australia/Darwin" time zone is `ACST`. + +For an example of its usage, refer to the <> function. +==== + [#manipulating-components] == Manipulating Date Components @@ -1302,7 +1312,7 @@ WHERE reviews[0].date BETWEEN "2013-01-01 %" AND "2014-01-01 %"; NOTE: When querying between two dates, you must specify the full date (with time and time zone) or use the wildcard character (%). [#fn-date-format-str] -== DATE_FORMAT_STR(date1, fmt) +== DATE_FORMAT_STR(date1, [input-fmt,] fmt) === Description @@ -1315,6 +1325,13 @@ A string, or any valid xref:n1ql-language-reference/index.adoc[expression] which + If this argument is not a valid date string then `null` is returned. +input-fmt:: +The format of the input string, `date1`. +This can be a string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string. ++ +*Optional argument*. +Only required if `date1` is not in a standard format or if the input and output formats are different. + fmt:: A string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string, representing a <> to output the result as. + @@ -1331,7 +1348,8 @@ A date string in the format specified. ---- SELECT DATE_FORMAT_STR('2016-05-15T00:00:23+00:00', '1111-11-11') as full_to_short, DATE_FORMAT_STR('2016-05-15', '1111-11-11T00:00:00+00:00') as short_to_full, - DATE_FORMAT_STR('01:10:05', '1111-11-11T01:01:01Z') as time_to_full; + DATE_FORMAT_STR('01:10:05', '1111-11-11T01:01:01Z') as time_to_full, + DATE_FORMAT_STR('15-MAY-2016', 'DD-MON-YYYY', 'YYYY-MM-DD') as month_to_numeric; ---- .Results @@ -1340,8 +1358,9 @@ SELECT DATE_FORMAT_STR('2016-05-15T00:00:23+00:00', '1111-11-11') as full_to_sho [ { "full_to_short": "2016-05-15", - "short_to_full": "2016-05-15T00:00:00-07:00", - "time_to_full": "0000-01-01T01:10:05-08:00" + "short_to_full": "2016-05-15T00:00:00Z", + "time_to_full": "0000-01-01T01:10:05Z", + "month_to_numeric": "2016-05-15" } ] ---- @@ -1801,15 +1820,15 @@ SELECT DATE_TRUNC_MILLIS(1463284740000, 'day') as day, [ { "day": 1463270400000, - "month": 1462147200000, - "year": 1451696400000 + "month": 1462060800000, + "year": 1451606400000 } ] ---- ==== [#fn-date-trunc-str] -== DATE_TRUNC_STR(date1, part) +== DATE_TRUNC_STR(date1, part [,fmt]) === Description @@ -1829,6 +1848,13 @@ This function accepts the components `millennium`, `century`, `decade`, `year`, + If an invalid part is specified, then `null` is returned. +fmt:: +The format of the input string, `date1`. +This can be a string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string. ++ +*Optional argument*. +Only required if `date1` is not in a standard format. + === Return Value A date string representing the truncated date. @@ -1840,7 +1866,8 @@ A date string representing the truncated date. ---- SELECT DATE_TRUNC_STR('2016-05-18T03:59:00Z', 'day') as day, DATE_TRUNC_STR('2016-05-18T03:59:00Z', 'month') as month, - DATE_TRUNC_STR('2016-05-18T03:59:00Z', 'year') as year; + DATE_TRUNC_STR('2016-05-18T03:59:00Z', 'year') as year, + DATE_TRUNC_STR('05/18/2016 03:59:00', 'month', 'MM/DD/YYYY HH24:MI:SS') as month_custom; ---- .Results @@ -1850,7 +1877,8 @@ SELECT DATE_TRUNC_STR('2016-05-18T03:59:00Z', 'day') as day, { "day": "2016-05-18T00:00:00Z", "month": "2016-05-01T00:00:00Z", - "year": "2016-01-01T00:00:00Z" + "year": "2016-01-01T00:00:00Z", + "month_custom": "05/01/2016 00:00:00" } ] ---- @@ -2596,12 +2624,13 @@ AS Milliseconds; ==== [#fn-date-str-to-utc] -== STR_TO_UTC(date1) +== STR_TO_UTC(date1 [, [input-fmt,] fmt]) === Description Converts a date string into the equivalent date in UTC. -The output date format follows the date format of the date passed as input. +By default, the output date format follows the date format of the date passed as input. +However, you can specify a different output format if needed. === Arguments @@ -2611,6 +2640,20 @@ This is the date to convert to UTC. + If this argument is not a valid date format, then `null` is returned. +input-fmt:: +The format of the input string, `date1`. +This can be a string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string. ++ +*Optional argument*. +Only required if `date1` is not in a standard format or if the input and output formats are different. + +fmt:: +The format of the resulting UTC date. +This can be a string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string, and must be a <>. ++ +*Optional argument*. +If not specified, the output date format follows the date format of the input string, `date1`. + === Return Value A single date string representing the date string converted to UTC. @@ -2621,7 +2664,8 @@ A single date string representing the date string converted to UTC. [source,sqlpp] ---- SELECT STR_TO_UTC('1111-11-11T00:00:00+08:00') as full_date, -STR_TO_UTC('1111-11-11') as short_date; + STR_TO_UTC('1111-11-11') as short_date, + STR_TO_UTC('1111-11-11', 'YYYY-MM-DD', 'YYYY-MM-DD HH:MI:SS') as utc_date; ---- .Results @@ -2630,19 +2674,21 @@ STR_TO_UTC('1111-11-11') as short_date; [ { "full_date": "1111-11-10T16:00:00Z", - "short_date": "1111-11-11" + "short_date": "1111-11-11", + "utc_date": "1111-11-11 12:00:00" } ] ---- ==== [#fn-date-str-to-tz] -== STR_TO_TZ(date1, tz) +== STR_TO_TZ(date1, tz [, [input-fmt,] fmt]) === Description Converts a date string to its equivalent in the specified timezone. -The output date format follows the date format of the date passed as input. +By default, the output date format follows the date format of the date passed as input. +However, you can specify a different output format if needed. === Arguments @@ -2657,10 +2703,25 @@ A string, or any valid xref:n1ql-language-reference/index.adoc[expression] which + If this argument is not a valid timezone, then `null` is returned. +input-fmt:: +The format of the input string, `date1`. +This can be a string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string. ++ +*Optional argument*. +Only required if `date1` is not in a standard format or if the input and output formats are different. + +fmt:: +The format of the output date. +This can be a string, or any valid xref:n1ql-language-reference/index.adoc[expression] which evaluates to a string, and must be a <>. ++ +*Optional argument*. +If not specified, the output date format follows the date format of the input string, `date1`. + === Return Value A single date string representing the date string converted to the specified timezone. +[[ex-str-to-tz]] === Examples ==== @@ -2668,7 +2729,10 @@ A single date string representing the date string converted to the specified tim ---- SELECT STR_TO_TZ('1111-11-11T00:00:00+08:00', 'America/New_York') as est, STR_TO_TZ('1111-11-11T00:00:00+08:00', 'UTC') as utc, - STR_TO_TZ('1111-11-11', 'UTC') as utc_short; + STR_TO_TZ('1111-11-11', 'UTC') as utc_short, + STR_TO_TZ('1111-11-11', 'UTC', 'YYYY-MM-DD', 'YYYY-MM-DD HH:MI:SS') as utc_datetime, + STR_TO_TZ('1111-11-11T00:00:00+07:00', 'Europe/Paris', + "YYYY-MM-DDThh:mm:ssTZD", "YYYY-MM-DDThh:mm:ssTZN") as tzn; ---- .Results @@ -2676,9 +2740,11 @@ SELECT STR_TO_TZ('1111-11-11T00:00:00+08:00', 'America/New_York') as est, ---- [ { - "est": "1111-11-10T11:00:00-05:00", + "est": "1111-11-10T11:03:58-04:56", "utc": "1111-11-10T16:00:00Z", - "utc_short": "1111-11-11" + "utc_short": "1111-11-11", + "utc_datetime": "1111-11-11 12:00:00", + "tzn": "1111-11-10T17:09:21LMT" } ] ---- From 02a7e104a5252152b274d17270dc87ffcd41929e Mon Sep 17 00:00:00 2001 From: Ray Offiah <77050471+RayOffiah@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:40:03 +0100 Subject: [PATCH 06/14] Merge pull request #385 * [DOC-13376]: Feedback on Read Data and Return Results | Couchbase Docs --- modules/guides/pages/select.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/guides/pages/select.adoc b/modules/guides/pages/select.adoc index 9f40b2dc1..1689492bf 100644 --- a/modules/guides/pages/select.adoc +++ b/modules/guides/pages/select.adoc @@ -56,7 +56,7 @@ The result includes each row found. [source,csharp] ---- -include::dotnet-sdk:hello-world:example$StartUsing.cs[tag=n1ql-query,indent=0] +include::dotnet-sdk:hello-world:example$StartUsing.csx[tag=n1ql-query,indent=0] ---- {github} @@ -70,7 +70,7 @@ The result object includes each row found. [source,java] ---- -include::java-sdk:hello-world:example$StartUsing.java[tag=n1ql-query,indent=0] +include::java-sdk:devguide:example$java/StartUsing.java[tag=n1ql-query,indent=0] ---- {github} @@ -305,7 +305,7 @@ Querying with SDKs: * xref:c-sdk:howtos:n1ql-queries-with-sdk.adoc[C] | xref:dotnet-sdk:howtos:n1ql-queries-with-sdk.adoc[.NET] | xref:go-sdk:howtos:n1ql-queries-with-sdk.adoc[Go] -| xref:java-sdk:howtos:n1ql-queries-with-sdk.adoc[Java] +| xref:java-sdk:howtos:sqlpp-queries-with-sdk.adoc[Java] | xref:nodejs-sdk:howtos:n1ql-queries-with-sdk.adoc[Node.js] | xref:php-sdk:howtos:n1ql-queries-with-sdk.adoc[PHP] | xref:python-sdk:howtos:n1ql-queries-with-sdk.adoc[Python] From 1a9ebe6d4296b88788cee716bc6e0ebfcfcb240c Mon Sep 17 00:00:00 2001 From: Ray Offiah <77050471+RayOffiah@users.noreply.github.com> Date: Wed, 6 Aug 2025 11:53:20 +0100 Subject: [PATCH 07/14] Merge pull request #389 * [DOC-13438]: Feedback on Date Functions | Couchbase Docs --- modules/n1ql/pages/n1ql-language-reference/datefun.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/n1ql/pages/n1ql-language-reference/datefun.adoc b/modules/n1ql/pages/n1ql-language-reference/datefun.adoc index 39a7f1e7f..63c197999 100644 --- a/modules/n1ql/pages/n1ql-language-reference/datefun.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/datefun.adoc @@ -65,6 +65,8 @@ Below are a few examples of commonly used timezones and their offsets: | +05:30 |==== +For a complete list of supported timezones, see https://www.iana.org/time-zones[the Timezone Database] + === Local System Timezone Many functions default to using the local timezone of the system, which will be one of the IANA timezones. From ff61bd643811d60214d8053e03274988e4e377b1 Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Wed, 6 Aug 2025 19:30:09 +0530 Subject: [PATCH 08/14] [DOC-10551] Additional object parameters and new object_filter function (#376) --- .../n1ql-language-reference/objectfun.adoc | 352 ++++++++++++++++-- 1 file changed, 324 insertions(+), 28 deletions(-) diff --git a/modules/n1ql/pages/n1ql-language-reference/objectfun.adoc b/modules/n1ql/pages/n1ql-language-reference/objectfun.adoc index df694f6d8..108f90822 100644 --- a/modules/n1ql/pages/n1ql-language-reference/objectfun.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/objectfun.adoc @@ -281,6 +281,169 @@ LIMIT 1; ---- ==== + +[[fn-obj-filter,OBJECT_FILTER()]] +== OBJECT_FILTER(`expression` [, `options`]) + +=== Description +This function extracts and returns nested fields from an input object that match a specified pattern, while retaining their original hierarchical path structure in the output. +This is particularly useful when working with complex objects, as it allows you to filter fields based on patterns using either regular expressions or exact matches. + +=== Arguments +expression:: An expression representing an object. + +options:: [Optional] A JSON object specifying options for the function. + +=== Options + +[options="header", cols="1a,3a,1a"] +|=== +| Name | Description | Schema + +| **pattern** + +__optional__ + +| The pattern to match. +This can be a regular expression or a simple string, depending on the `regex` parameter. +| String + +| **regex** + +__optional__ +| If `TRUE`, the pattern is treated as a regular expression. + +If `FALSE`, the pattern is treated as a simple string. + +*Default:* `TRUE` +| Boolean + +| **arraysubscript** + +__optional__ +| Specifies whether array subscripts are included in field names before applying the filter. + +If `TRUE`, array subscripts are included. + +If `FALSE`, array subscripts are replaced by `*`. + +*Default:* `TRUE` + +| Boolean + +| **composites** + +__optional__ +| Specifies whether the pattern should match field names that contain values requiring further processing, such as nested objects or arrays. + +If `TRUE`, the pattern is matched against every level of nested fields. + +If `FALSE`, the pattern is matched only against the deepest level of nested fields. + +*Default:* `TRUE` +| Boolean + +| **patternspace** + +__optional__ +| A string literal with two possible values. + +`"field"`: The pattern is matched against individual field names. + +`"path"`: The pattern is matched against composite path names. + +*Default:* `"path"` +| String + +| **exact** + +__optional__ +| Specifies whether the provided pattern must be an exact match for the field or path (as determined by the `patternspace` parameter). + +This is a short-cut for the regular expression start (^) and end ($) anchors, and can be used even when `regex` is set to `false`. + +If `TRUE`, the pattern must be an exact match. + +If `FALSE`, the pattern does not need to be an exact match. + +*Default:* `FALSE` +| Boolean + +| **ignorecase** + +__optional__ +| If `TRUE`, the pattern matching is case-sensitive. + +If `FALSE`, the pattern matching ignores case. + +*Default:* `FALSE` +| Boolean +|=== + +=== Return Value +An object containing only the fields that match the specified pattern. +Non-matching fields are excluded from the output. + +=== Examples + +[[obj-filter-ex1,OBJECT_FILTER() Example 1]] +.Filtering by field name +==== +.Query +[source,sqlpp] +---- +SELECT OBJECT_FILTER(t, {"pattern":"Business service"}) +FROM `travel-sample`.`inventory`.`hotel` t +WHERE type = 'hotel' +LIMIT 2; +---- +.Results +[source,json] +---- +[ + { + "$1": { + "reviews": [ + { + "ratings": { + "Business service (e.g., internet access)": 4 + } + } + ] + } + }, + { + "$1": null + } +] +---- +==== + +[[obj-filter-ex2,OBJECT_FILTER() Example 2]] +.Filtering by full path +You can use <> to generate the full path to a field, and then use that path in the `pattern` parameter. +==== +.Query +[source,sqlpp] +---- +SELECT OBJECT_FILTER(t, { "pattern": "reviews[1].ratings.Service", "regex": false }) +FROM `travel-sample`.`inventory`.`hotel` t +WHERE type = 'hotel' +LIMIT 1; +---- +.Results +[source,json] +---- +[ + { + "$1": { + "reviews": [ + { + "ratings": { + "Service": 3 + } + } + ] + } + } +] +---- +==== + + [[fn-obj-inner-pairs,OBJECT_INNER_PAIRS()]] == OBJECT_INNER_PAIRS(`expression`) @@ -825,23 +988,81 @@ If FALSE, only the deepest possible nested fields are returned. *Default:* `FALSE` | Boolean +| **types** + +__optional__ +| Determines whether to return field types or values. + +If TRUE, the function returns the name and type of each field. + +If FALSE, the function returns the name and value of each field. + +*Default:* `FALSE` +| Boolean + | **pattern** + __optional__ -| A regular expression used to filter the returned paths. -The pattern is matched against the composite path names, not the individual field names. +| The pattern used to filter the returned paths. + +It can be a regular expression or a simple string, depending on the `regex` parameter. | String -| **types** + +| **regex** + __optional__ -| Determines whether to return field types or values. +| If `TRUE`, the pattern is treated as a regular expression. -If TRUE, the function returns the name and type of each field. +If `FALSE`, the pattern is treated as a simple string. -If FALSE, the function returns the name and value of each field. +*Default:* `TRUE` +| Boolean + +| **patternspace** + +__optional__ +| A string literal with two possible values. + +`"field"`: The pattern is matched against individual field names. + +`"path"`: The pattern is matched against composite path names. + +*Default:* `"path"` +| String + +| **exact** + +__optional__ +| Determines whether the provided pattern must be an exact match for the field or path (as determined by the `patternspace` parameter). + +This is a short-cut for the regular expression start (^) and end ($) anchors, and can be used even when `regex` is set to `false`. + +If `TRUE`, the pattern must be an exact match. + +If `FALSE`, the pattern does not need to be an exact match. *Default:* `FALSE` | Boolean + +| **ignorecase** + +__optional__ +| If `TRUE`, the pattern matching is case-sensitive. + +If `FALSE`, the pattern matching ignores case. + +*Default:* `FALSE` +| Boolean + +| **report** + +__optional__ + +| Controls the output of the `name` field, allowing selection between the full path or the final field name. + +Possible values are: + +`"field"`: Outputs only the final field name. + +`"path"`: Outputs the full path to the field. + +*Default:* `"path"` + +| String |=== === Return Value @@ -886,7 +1107,10 @@ WITH input AS ({ SELECT OBJECT_PAIRS_NESTED(input) AS nested_pairs, OBJECT_PAIRS_NESTED(input, {"composites": true}) AS nested_pairs_comp, OBJECT_PAIRS_NESTED(input, {"pattern": "name"}) AS nested_pairs_pattern, - OBJECT_PAIRS_NESTED(input, {"types": true}) AS nested_pairs_types; + OBJECT_PAIRS_NESTED(input, {"types": true}) AS nested_pairs_types, + OBJECT_PAIRS_NESTED(input, {"pattern": "number", "patternspace":"field"}) AS filtered_fields, + OBJECT_PAIRS_NESTED(input, {"pattern": "-name$", "patternspace":"field", "regex":true}) + AS filtered_fields_regex; ---- .Results @@ -936,6 +1160,18 @@ SELECT OBJECT_PAIRS_NESTED(input) AS nested_pairs, "name": "attribute.flight-number", "type": "number" } + ], + "filtered_fields": [ + { + "name": "attribute.flight-number", + "val": 737 + } + ], + "filtered_fields_regex": [ + { + "name": "attribute.flight-name", + "val": "AI444" + } ] } ] @@ -1063,31 +1299,86 @@ A field in this context may be any attribute or element, nested at any level wit object:: An expression representing an object. -options:: [Optional] An object containing the following possible parameters: +options:: [Optional] An object containing the following possible parameters. + +=== Options + +[options="header", cols="1a,3a,1a"] +|=== +| Name | Description | Schema + +| **composites** + +__optional__ +| If `TRUE`, every level of every nested field is displayed. + +If `FALSE`, only the deepest possible nested fields are returned. + +*Default:* `TRUE` +| Boolean + +| **arraysubscript** + +__optional__ +| If `TRUE`, array subscripts are returned. + +If `FALSE`, array subscripts are replaced by `*`. -composites;; A boolean. -If `true`, every level of every nested field is displayed; if `false`, only the deepest possible nested fields are returned. -Default `true`. +*Default:* `TRUE` +| Boolean + +| **unique** + +__optional__ +| If `TRUE`, duplicate field names are collapsed to single unique field name. -arraysubscript;; A boolean. -If `true`, array subscripts are returned; if `false`, array subscripts are replaced by `*`. -Default `true`. +If `FALSE`, all duplicate field names are returned. -unique;; A boolean. -If `true`, duplicate field names are collapsed to single unique field name; if `false`, all duplicate field names are returned. Typically used when arrays are expanded and array subscripts are not returned. -Default `true`. -pattern;; A regular expression used to filter the returned paths. -Used in conjunction with the following setting. +*Default:* `TRUE` +| Boolean -patternspace;; A string literal with two possible values. -Default `"path"`. -+ -[horizontal] -`"field"`::: The pattern is matched against individual field names. +| **pattern** + +__optional__ +| A regular expression used to filter the returned paths. +Used in conjunction with the `patternspace` setting. -`"path"`::: The pattern is matched against composite path names. +| String + +| **patternspace** + +__optional__ + +| A string literal with two possible values. + +`"field"`: The pattern is matched against individual field names. + +`"path"`: The pattern is matched against composite path names. + +*Default:* `"path"` + +| String + +| **exact** + +__optional__ +| Determines whether the provided pattern must be an exact match for the field or path (as determined by the `patternspace` parameter). + +This is a short-cut for the regular expression start (^) and end ($) anchors, and can be used even when `regex` is set to `false`. + +If `TRUE`, the pattern must be an exact match. + +If `FALSE`, the pattern does not need to be an exact match. + +*Default:* `FALSE` +| Boolean + +| **ignorecase** + +__optional__ +| If `TRUE`, the pattern matching is case-sensitive. + +If `FALSE`, the pattern matching ignores case. + +*Default:* `FALSE` +| Boolean + +|=== === Return Value @@ -1179,7 +1470,7 @@ SELECT [[obj-paths-ex3,OBJECT_PATHS() Example 3]] .Pattern matching and pattern space ==== -This example searches for strings beginning with "n" in the given object paths. +This example searches for strings beginning with "n" and also fields that exactly match "name". .Query [source,sqlpp] @@ -1193,7 +1484,9 @@ SELECT OBJECT_PATHS(input, {"pattern": "^n", "patternspace": "field"}) AS field_starts_with_n, OBJECT_PATHS(input, {"pattern": "^n", "patternspace": "path"}) - AS path_starts_with_n; + AS path_starts_with_n, + OBJECT_PATHS(input, {"pattern": "name", "patternspace": "field", "exact": true}) + AS exact_field_name; ---- .Results @@ -1208,7 +1501,10 @@ SELECT "field_starts_with_n": [ "attribute.name" ], - "path_starts_with_n": [] + "path_starts_with_n": [], + "exact_field_name": [ + "attribute.name" + ] } ] ---- From 64c61149ec92c87ee487cbcaed12fff50a10ad0e Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Thu, 7 Aug 2025 14:58:15 +0530 Subject: [PATCH 09/14] [DOC-10590] Add EXCLUDE clause to SELECT (#382) --- .../exclude-clause.png | Bin 0 -> 5906 bytes .../n1ql-language-reference/exclude-term.png | Bin 0 -> 4448 bytes .../n1ql-language-reference/select-clause.png | Bin 5817 -> 7603 bytes .../select-syntax.adoc | 18 +++- .../n1ql-language-reference/selectclause.adoc | 88 ++++++++++++++++++ modules/n1ql/partials/grammar/dql.ebnf | 10 +- 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 modules/n1ql/assets/images/n1ql-language-reference/exclude-clause.png create mode 100644 modules/n1ql/assets/images/n1ql-language-reference/exclude-term.png diff --git a/modules/n1ql/assets/images/n1ql-language-reference/exclude-clause.png b/modules/n1ql/assets/images/n1ql-language-reference/exclude-clause.png new file mode 100644 index 0000000000000000000000000000000000000000..cb7a8b1012ce74fa69a1aa1acd1aa6d340cbe400 GIT binary patch literal 5906 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 literal 0 HcmV?d00001 diff --git a/modules/n1ql/assets/images/n1ql-language-reference/exclude-term.png b/modules/n1ql/assets/images/n1ql-language-reference/exclude-term.png new file mode 100644 index 0000000000000000000000000000000000000000..526de6c4f4c1877db3fec75d395112d4a842fe49 GIT binary patch literal 4448 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 diff --git a/modules/n1ql/pages/n1ql-language-reference/select-syntax.adoc b/modules/n1ql/pages/n1ql-language-reference/select-syntax.adoc index d4e426eec..38e219f73 100644 --- a/modules/n1ql/pages/n1ql-language-reference/select-syntax.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/select-syntax.adoc @@ -5,6 +5,7 @@ :page-topic-type: reference :expression: xref:n1ql-language-reference/index.adoc#N1QL_Expressions +:string-expression: xref:n1ql-language-reference/literals.adoc#strings :hints: xref:n1ql-language-reference/optimizer-hints.adoc :conventions: xref:n1ql-language-reference/conventions.adoc :number: xref:n1ql-language-reference/literals.adoc#numbers @@ -81,7 +82,7 @@ image::n1ql-language-reference/alias.png["Syntax diagram", align=left] [subs="normal"] ---- -select-clause ::= 'SELECT' {hints}[hint-comment]? <> +select-clause ::= 'SELECT' {hints}[hint-comment]? <> <>? ---- image::n1ql-language-reference/select-clause.png["Syntax diagram", align=left] @@ -109,6 +110,21 @@ path ::= {identifier}[identifier] ( '[' {expression}[expr] ']' )* ( '.' {identif image::n1ql-language-reference/path.png["Syntax diagram", align=left] +[#exclude-clause,reftext="exclude-clause",subs="normal"] +---- +exclude-clause ::= 'EXCLUDE' <> ( ',' <> )* +---- + +image::n1ql-language-reference/exclude-clause.png["Syntax diagram", align=left] + +[#exclude-term,reftext="exclude-term",subs="normal"] +---- +exclude-term ::= {identifier}[identifier] | {string-expression}[string-expr] +---- +image::n1ql-language-reference/exclude-term.png["Syntax diagram", align=left] + +[#hints,reftext="hints",subs="normal"] + [[from-clause,from-clause]] == FROM Clause diff --git a/modules/n1ql/pages/n1ql-language-reference/selectclause.adoc b/modules/n1ql/pages/n1ql-language-reference/selectclause.adoc index 0080da7d4..dff382d14 100644 --- a/modules/n1ql/pages/n1ql-language-reference/selectclause.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/selectclause.adoc @@ -34,6 +34,7 @@ image::n1ql-language-reference/select-clause.png["Syntax diagram", align=left] [horizontal.compact] hint-comment:: <> icon:caret-down[] projection:: <> icon:caret-down[] +exclude-clause:: <> icon:caret-down[] [#hint-comment] === Optimizer Hints @@ -155,6 +156,47 @@ If you do not explicitly give a field an alias, it is given an _implicit alias_. An implicit or explicit alias is returned in the result set, unless you suppress it using the <>. +[#sec_ExcludeClause] +=== EXCLUDE Clause + +[source,ebnf] +---- +include::partial$grammar/dql.ebnf[tag=exclude-clause] +---- +image::n1ql-language-reference/exclude-clause.png["Syntax diagram", align=left] + +The EXCLUDE clause removes specific fields from your query's result set. + +Instead of listing every field you want to include in the SELECT statement, use EXCLUDE to specify only the ones you want to omit. +This is particularly useful when you use the star expression (`{asterisk}`) to select all fields, but want to exclude a few. + +The clause consists of one or more <>, separated by commas. + +[[exclude-term]] +==== EXCLUDE Term +[source,ebnf] +---- +include::partial$grammar/dql.ebnf[tag=exclude-term] +---- +image::n1ql-language-reference/exclude-term.png["Syntax diagram", align=left] + +An EXCLUDE term is a field that you want to exclude from the final projection. +It must exactly match the field name or alias as it appears in the projection. +Refer to <>. + +An EXCLUDE term can be: + +* An identifier, such as `hotel.name`. +* A string expression with one or more fields separated by commas, such as `"hotel.name, address"`. + +[NOTE] +==== +* If the field has an alias, you must use the alias as the term. +* When your query includes only one FROM term, fields are automatically qualified with it. +You can use the field name without the full identifier. +For example, `name` instead of `hotel.name`. +==== + [#sec_BestPractices] == Best Practices @@ -632,6 +674,52 @@ FROM hotel LIMIT 5; <.> With a select expression, you may optionally include the keyspace name; in either case, the keyspace name is not added to the results. ==== +[[ex-exclude-clause]] +.SELECT with an EXCLUDE clause +==== +.Query +[source,sqlpp] +---- +SELECT * EXCLUDE reviews,h.public_likes,"geo,description" +FROM `travel-sample`.inventory.hotel h +ORDER BY meta().id LIMIT 1; +---- + +.Results +[source,json] +---- +[ + { + "h": { + "address": "Capstone Road, ME7 3JE", + "alias": null, + "checkin": null, + "checkout": null, + "city": "Medway", + "country": "United Kingdom", + "directions": null, + "email": null, + "fax": null, + "free_breakfast": true, + "free_internet": false, + "free_parking": true, + "id": 10025, + "name": "Medway Youth Hostel", + "pets_ok": true, + "phone": "+44 870 770 5964", + "price": null, + "state": null, + "title": "Gillingham (Kent)", + "tollfree": null, + "type": "hotel", + "url": "http://www.yha.org.uk", + "vacancy": true + } + } +] +---- +==== + [#sec_RelatedLinks] == Related Links diff --git a/modules/n1ql/partials/grammar/dql.ebnf b/modules/n1ql/partials/grammar/dql.ebnf index ff47759c9..0b3612d97 100644 --- a/modules/n1ql/partials/grammar/dql.ebnf +++ b/modules/n1ql/partials/grammar/dql.ebnf @@ -71,10 +71,11 @@ anchor-select ::= select /* tag::recursive-select-term[] */ recursive-select-term ::= select-term /* end::recursive-select-term[] */ + /* SELECT Clause */ /* tag::select-clause[] */ -select-clause ::= 'SELECT' hint-comment? projection +select-clause ::= 'SELECT' hint-comment? projection exclude-clause? /* end::select-clause[] */ hint-comment ::= [https://github.com/couchbaselabs/docs-devex/blob/release/8.0/modules/n1ql/partials/grammar/hints.ebnf] @@ -92,6 +93,13 @@ result-expr ::= ( path '.' )? '*' | expr ( 'AS'? alias )? path ::= identifier ( '[' expr ']' )* ( '.' identifier ( '[' expr ']' )* )* /* end::path[] */ +/* tag::exclude-clause[] */ +exclude-clause ::= 'EXCLUDE' exclude-term ( ',' exclude-term )* +/* end::exclude-clause[] */ + +/* tag::exclude-term[] */ +exclude-term ::= identifier | string-expression +/* end::exclude-term[] */ /* FROM Clause */ From 7676c00877c6c21c55dac1651c1ed4e65948bbc6 Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Mon, 11 Aug 2025 15:10:07 +0530 Subject: [PATCH 10/14] [DOC-10552] Changes to array operators and functions (#371) --- .../n1ql-language-reference/slice-expr.png | Bin 5818 -> 5860 bytes .../n1ql-language-reference/arrayfun.adoc | 113 ++++++++++++++++++ .../n1ql-language-reference/nestedops.adoc | 6 +- modules/n1ql/partials/grammar/n1ql.ebnf | 2 +- 4 files changed, 119 insertions(+), 2 deletions(-) diff --git a/modules/n1ql/assets/images/n1ql-language-reference/slice-expr.png b/modules/n1ql/assets/images/n1ql-language-reference/slice-expr.png index a02b7242c4c327b2ccc32098bfe431de415c4f9a..ad0efc41c02ba368a236d15247782985e175b912 100644 GIT binary patch delta 5798 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 literal 5818 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 NG7^g7rJ@D_{{|>3UN!&# diff --git a/modules/n1ql/pages/n1ql-language-reference/arrayfun.adoc b/modules/n1ql/pages/n1ql-language-reference/arrayfun.adoc index 775589b7a..30423e54b 100644 --- a/modules/n1ql/pages/n1ql-language-reference/arrayfun.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/arrayfun.adoc @@ -1497,6 +1497,119 @@ SELECT array_star(children).age FROM contacts WHERE fname = "Dave" ---- ==== +=== Empty Array Subscripts + +You can use an empty array subscript (`[ ]`) to return an array that includes only defined elements. + +The rules governing its use are as follows: + +[cols="1a,2a"] +|==== +| Expression | Description + +| `field[]` +|* If `field` is not an array, it returns `NULL`. +* If `field` is an array, it returns the array as is. + + +| `field[][]` +|* If `field` is not an array, it returns `NULL`. +* If `field` contains only unnamed arrays, it returns `field` as is. +Otherwise, it returns `NULL`. + +| `field[].field2` +|* If `field` is not an array, it returns `MISSING`. +* If `field` is an array, it extracts `field2` from each element in `field` and returns a new array with those values. +* If `field` contains unnamed arrays, they are flattened by one level. +Then from the resulting array, it extracts `field2` from each object where it is present. + +| `field[][].field2` +|* If `field` is not an array, it returns `MISSING`. +* If every element in `field` is not an unnamed array, it returns `MISSING`. +* If `field` contains unnamed arrays, they are flattened by one level. +Then from the resulting array, it extracts `field2` from each object where it is present. + + +| `field[].field2[].field3` +|* Returns an array of `field3` values by traversing two levels of arrays. +First it extracts `field2` from each element of `field`, then extracts `field3` from each element of the resulting `field2` array. +* If `field` and `field2` contain unnamed arrays, they are flattened by one level. +Then from the resulting `field2` array, it extracts `field3` from each object where it is present. + +|==== + +NOTE: If you use more that two empty array subscripts (for example, `field[][][]`), the function considers only the first two subscripts and ignores the rest. + +==== Example + +==== +Given the following sample document: + +[source,json] +---- +{ + "a": { + "airline": "AF", + "airlineid": "airline_003", + "destinationairport": "SFO", + "distance": 2481.617376098415, + "equipment": "320", + "id": 3, + "schedule": [ + { + "day": 0, + "flight": "AF198", + "utc": "10:13:00" + }, + { + "flight": "AF250", + "utc": "12:59:00" + }, + { + "day": 2, + "flight": "AF223", + "special_flights": [ + { + "a": "SA" + }, + { + "b": [ + [ + { + "c": "SC1" + }, + { + "c": "SC2" + } + ], + [ + { + "c": "SC3" + } + ] + ] + } + ], + "utc": "19:41:00" + } + ], + "sourceairport": "DFW" + } +} +---- + +Here's how different array subscripts evaluate: + +* `a.airline[]`: Returns `NULL` (not an array). +* `a.schedule[]`: Equivalent to `a.schedule`, returns the array. +* `a.schedule[].day`: Returns `[0, 2]`. This is in contrast to `a.schedule[*].day`, which returns `[0, null, 2]`. +* `a.schedule[].special_flights[].a`: Returns `["SA"]`. +* `a.schedule[][].utc`: Returns `MISSING`. +* `a.schedule[].special_flights[].b[][].c`: Returns `["SC1", "SC2", "SC3"]`. +* `a.schedule[].special_flights[].b[].c`: Also returns `["SC1", "SC2", "SC3"]`, as the unnamed arrays are flattened. + +==== + [[fn-array-sum,ARRAY_SUM()]] == ARRAY_SUM([.var]`expr`) diff --git a/modules/n1ql/pages/n1ql-language-reference/nestedops.adoc b/modules/n1ql/pages/n1ql-language-reference/nestedops.adoc index d9540795f..a07fdca28 100644 --- a/modules/n1ql/pages/n1ql-language-reference/nestedops.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/nestedops.adoc @@ -132,7 +132,7 @@ expr:: An expression resolving to an array. start-expr:: -A numeric expression specifying a start position in the array, counting from 0. +[Optional] A numeric expression specifying a start position in the array, counting from 0. Negative positions are counted backwards from the end of the array. end-expr:: @@ -144,6 +144,8 @@ Negative positions are counted backwards from the end of the array. A new subset of the source array, containing the elements from the start position to the end position minus 1. The element at the start position is included, while the element at the end position is not. +If the start position is omitted, the subset starts from the beginning of the source array. + If the end position is omitted, all elements from the start position to the end of the source array are included. === Example @@ -164,4 +166,6 @@ Given the following data: The expression `revisions[1:3]` evaluates to the array value `[2012, 2011]`. The expression `revisions[1:]` evaluates to the array value `[2012, 2011, 2010]`. + +The expression `revisions[:2]` evaluates to the array value `[2013, 2012]`. ==== diff --git a/modules/n1ql/partials/grammar/n1ql.ebnf b/modules/n1ql/partials/grammar/n1ql.ebnf index 357a1a45e..938b868e9 100644 --- a/modules/n1ql/partials/grammar/n1ql.ebnf +++ b/modules/n1ql/partials/grammar/n1ql.ebnf @@ -260,7 +260,7 @@ element-expr ::= expr '[' position ']' /* end::element-expr[] */ /* tag::slice-expr[] */ -slice-expr ::= expr '[' start-expr ':' end-expr? ']' +slice-expr ::= expr '[' start-expr? ':' end-expr? ']' /* end::slice-expr[] */ start-expr ::= expr From 14a1f65ba65f0c5e7ebe260f3b90eb57d533ef7b Mon Sep 17 00:00:00 2001 From: Ray Offiah <77050471+RayOffiah@users.noreply.github.com> Date: Fri, 22 Aug 2025 16:30:34 +0100 Subject: [PATCH 11/14] Merge pull request #402 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [DOC-13489]: Feedback on Run A Vector Search with the Server Web Cons… --- modules/vector-search/pages/run-vector-search-ui.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/vector-search/pages/run-vector-search-ui.adoc b/modules/vector-search/pages/run-vector-search-ui.adoc index 2cf5996f0..8f6cbd648 100644 --- a/modules/vector-search/pages/run-vector-search-ui.adoc +++ b/modules/vector-search/pages/run-vector-search-ui.adoc @@ -103,7 +103,7 @@ include::example$run-vector-search-long-payload-ui.jsonc[tag=partial] ==== Due to the size of the embedding vector, only part of the full query is being displayed in the documentation. -Click btn:[View on GitHub] to view and copy the entire Vector Search query payload. +Click btn:[View] to view and copy the entire Vector Search query payload. Make sure you remove the lines for `// tag::partial[]` and `// end::partial[]`. ==== From 7621e10fb37682d72f73bf0ef0ff0f02073c241c Mon Sep 17 00:00:00 2001 From: Pallavi-Janardhan Date: Tue, 26 Aug 2025 18:35:07 +0530 Subject: [PATCH 12/14] Doc 13470 add example code snippet for on deploy (#401) * Doc_13470_Adding example code snippet for OnDeploy * Doc_13470_Adding example code snippet for OnDeploy * DOC_13470_Adding more info from the SME Changed the info according to SME comments and created a hyperlink to another file. * Added an xref link to another topic in a diff file * Added an xref link to the function settings section in a diff file * Added an xref link to the function settings section in a diff file * Doc_13470_Adding text as per the SME * DOC_13470 Adding info on OnDeploy Timeout as per the SME * DOC_13470 Adding info on OnDeploy Timeout as per the SME * DOC_13470 Adding info on OnDeploy Timeout as per the SME --- .../pages/eventing-Terminologies.adoc | 11 +++++-- .../pages/eventing-language-constructs.adoc | 30 +++++++++++++++++-- .../eventing/pages/eventing-lifecycle.adoc | 12 ++++++-- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/modules/eventing/pages/eventing-Terminologies.adoc b/modules/eventing/pages/eventing-Terminologies.adoc index a1d893991..609efe874 100644 --- a/modules/eventing/pages/eventing-Terminologies.adoc +++ b/modules/eventing/pages/eventing-Terminologies.adoc @@ -59,9 +59,9 @@ It is not possible to get the value of a document that has been deleted or expir ==== `OnDeploy` -The `OnDeploy` handler runs once when an Eventing function is deployed or resumed. +The `OnDeploy` handler runs once when an Eventing function is deployed or resumed, before any mutations are processed. -The entry point `OnDeploy(action)` receives an `action` parameter, like `deploy` or `resume`, indicating the reason for invocation. It also includes a `delay` value (in milliseconds), showing the time since the function was paused. For deployment operations, this value is `0` +The entry point `OnDeploy(action)` receives an `action` parameter, like `deploy` or `resume`, indicating the reason for invocation. It also includes a `delay` value (in milliseconds), showing the time since the function was paused. For deployment operations, this value is `0`. *Limitation*: Avoid long-running operations within the `OnDeploy` as they can delay function deployment. @@ -336,6 +336,13 @@ Versions 6.0.0 and 6.5.0 filter all binary documents out of the DCP mutation str The entry points into the handler processing for each mutation must run from start to finish before the specified timeout duration. The default number of seconds is `60`. +|OnDeploy Timeout +|The number of seconds to elapse before the OnDeploy entry point times out and terminates. + +The timeout is set to `60` seconds, by default. + +The OnDeploy Timeout defines the maximum duration allowed for an Eventing Function to complete its initialization during deployment or resumption. + |Time Context Max Size |The size limit of the context for any Timer created by the Eventing Function. diff --git a/modules/eventing/pages/eventing-language-constructs.adoc b/modules/eventing/pages/eventing-language-constructs.adoc index 0b8675bc8..532bd9c38 100644 --- a/modules/eventing/pages/eventing-language-constructs.adoc +++ b/modules/eventing/pages/eventing-language-constructs.adoc @@ -562,17 +562,18 @@ The Eventing Service calls the following JavaScript functions on events like mut * <> * <> +* <> * <> [#onupdate_handler] === OnUpdate Handler -The `OnUpdate` handler is called when you create or modify a document using an operation like insert or update. +The `OnUpdate` handler is called when you create or modify a document. The entry point `OnUpdate(doc, meta)` listens to mutations in the associated source bucket. The `OnUpdate` handler has the following limitations: -* If a document is modified several times in a short period of time, the handler calls might be combined into a single event due to deduplication. +* If a document is modified several times in a short period of time, the handler calls can merge into a single event due to deduplication. * You cannot distinguish between a Create and an Update operation. [source,javascript] @@ -622,6 +623,31 @@ function OnDelete(meta) { } ---- +[#ondeploy_handler] +=== OnDeploy Handler + +The `OnDeploy` handler is invoked once when an Eventing function is deployed or resumed, before any mutations are processed. +The entry point `OnDeploy(action)` is used for one-time setup tasks like resource initialization, creation of timers, and so on. + +The `OnDeploy` handler has a limitation. Avoid any long-running operations within the `OnDeploy` as they can delay function deployment. + +The timeout for OnDeploy execution is configurable separately in the xref:eventing:eventing-Terminologies.adoc#function-settings[Eventing Function Settings]. + +---- +function OnDeploy(action) { + log("OnDeploy triggered. Reason:", action.reason, "Delay (ms):", action.delay); + + if (action.reason === "deploy") { + // Perform operations for fresh deployment (like timer creation, resource initialisation) + log("Deploy: perform first time setup for function"); + } + else if (action.reason === "resume") { + // Function was paused and resumed: refresh any cached information + log("Resume: perform operations before function resumption"); + } +} +---- + [#timer_callback_handler] === Timer Callback Handler diff --git a/modules/eventing/pages/eventing-lifecycle.adoc b/modules/eventing/pages/eventing-lifecycle.adoc index 3db4de8c5..97940ed8c 100644 --- a/modules/eventing/pages/eventing-lifecycle.adoc +++ b/modules/eventing/pages/eventing-lifecycle.adoc @@ -127,10 +127,14 @@ The minimum value is 1 (the default) and the recommended maximum is 64. If the semantics of a language construct change in any given release the “Language compatibility” setting will ensure an older Eventing Function will continue to see the runtime behavior that existed at the time it was authored, until such behavior is deprecated and removed. Note 6.0.0, 6.5.0, and 6.6.2 (the default) are the only currently defined versions. * *Script Timeout*: Script Timeout provides a timeout option to terminate a non-responsive Function. -The entry points into the Eventing Function, like OnUpdate and OnDelete, processing for each mutation must complete from start to finish prior to this specified timeout duration. The default is 60 seconds. In addition an Timer callback must also complete within this period. +The entry points into the Eventing Function, like OnUpdate and OnDelete, processing for each mutation must complete from start to finish prior to this specified timeout duration. +The default is 60 seconds. +In addition an Timer callback must also complete within this period. * *OnDeploy Timeout*: OnDeploy Timeout defines the maximum duration allowed for an Eventing Function to complete its initialization during deployment or resumption. -The OnDeploy entry point must complete execution, from start to end, within the specified timeout period. If the runtime exceeds the specified duration, the function is reverted to its previous state. By default, the timeout is set to 60 seconds. +The OnDeploy entry point must complete execution, from start to end, within the specified timeout period. +If the runtime exceeds the specified duration, the function is reverted to its previous state. +By default, the timeout is set to 60 seconds. * *Timer Context Max Size*: Timer Context Max Size limits the size of the context for any Timer created by the Function. Eventing Timers can store and access a context which can be any JSON document, the context is used to store state when the timer is created and retrieve state when the timer fires. By default the size is 1024 bytes, but this can be adjusted on a per Function basis. @@ -147,7 +151,9 @@ Currently Eventing Functions support the following binding types: * *Constant Bindings*: to pass global settings/constants into the function. -An Eventing Function can have no bindings, just one binding, or several bindings. For more information on Bindings, refer to xref:eventing-Terminologies.adoc#section_mzd_l1p_m2b[Terminologies - Bindings]. +An Eventing Function can have no bindings, just one binding, or several bindings. +For more information on Bindings, refer to xref:eventing-Terminologies.adoc#section_mzd_l1p_m2b[Terminologies - Bindings]. + |=== . In the *ADD FUNCTION* dialog, configure the following information: From df124d118d076e12a55f805a85fea73244503f4a Mon Sep 17 00:00:00 2001 From: rakhi-prathap Date: Thu, 28 Aug 2025 16:14:06 +0530 Subject: [PATCH 13/14] [DOC-12664] Automatic Workload Repository (AWR) (#342) --- modules/n1ql/pages/n1ql-intro/sysinfo.adoc | 1 + modules/n1ql/pages/n1ql-manage/index.adoc | 2 + modules/n1ql/pages/n1ql-manage/query-awr.adoc | 478 ++++++++++++++++++ modules/n1ql/partials/nav.adoc | 1 + 4 files changed, 482 insertions(+) create mode 100644 modules/n1ql/pages/n1ql-manage/query-awr.adoc diff --git a/modules/n1ql/pages/n1ql-intro/sysinfo.adoc b/modules/n1ql/pages/n1ql-intro/sysinfo.adoc index 2b0678b80..240246a79 100644 --- a/modules/n1ql/pages/n1ql-intro/sysinfo.adoc +++ b/modules/n1ql/pages/n1ql-intro/sysinfo.adoc @@ -57,6 +57,7 @@ xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-active-req[system:active_re xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-prepared[system:prepareds] xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-completed-req[system:completed_requests] xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-history[system:completed_requests_history] +xref:n1ql:n1ql-manage/query-awr.adoc[system:awr] a| [%hardbreaks] <> diff --git a/modules/n1ql/pages/n1ql-manage/index.adoc b/modules/n1ql/pages/n1ql-manage/index.adoc index b1cd9b63a..d26f8171d 100644 --- a/modules/n1ql/pages/n1ql-manage/index.adoc +++ b/modules/n1ql/pages/n1ql-manage/index.adoc @@ -31,6 +31,7 @@ You can monitor and manage queries using the Couchbase Web Console, the command * xref:tools:query-monitoring.adoc[] * xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc[] +* xref:n1ql:n1ql-manage/query-awr.adoc[] == Manage Primary and Secondary Indexes @@ -44,3 +45,4 @@ You can monitor and manage primary and secondary indexes using the Couchbase Web You can configure the Query service using cluster-level query settings, node-level query settings, and request-level query parameters. * xref:n1ql:n1ql-manage/query-settings.adoc[] + diff --git a/modules/n1ql/pages/n1ql-manage/query-awr.adoc b/modules/n1ql/pages/n1ql-manage/query-awr.adoc new file mode 100644 index 000000000..19c8ed422 --- /dev/null +++ b/modules/n1ql/pages/n1ql-manage/query-awr.adoc @@ -0,0 +1,478 @@ += Automatic Workload Repository +:page-status: Couchbase Server 8.0 +:description: Monitor and optimize query performance and workload using Automatic Workload Repository (AWR). +:page-toclevels: 2 + +[abstract] +{description} + +== Overview + +Automatic Workload Repository (AWR) is a feature that captures and maintains performance statistics for queries executed on your Couchbase cluster. +It acts as a centralized repository for query performance data, enabling you to monitor and analyze query activity and workload over time. + +By providing a historical view of query behavior, AWR makes it easier to identify trends and performance bottlenecks. +For example, some queries may run efficiently with minimal overhead, while others may consume more resources or take longer to complete. +With AWR, you can understand these differences and optimize your queries accordingly. + +When enabled, AWR automatically gathers detailed metrics from the Query Service for every query that you run on your cluster. +This includes metrics such as execution time, CPU usage, memory consumption, number of executions, and more. +It then aggregates this data into <> and stores them in a <>. + +You can access the collected data by directly querying the <> or by using Couchbase's report generation tool to generate reports and compare query performance across different time periods. +For more information, see <>. + +== Use Cases + +Here are some scenarios where AWR can be effectively utilized to enhance query performance and workload: + +* **Troubleshooting Real-Time Issues**: +You can quickly identify slow running queries or instances of high resource usage. +You can extract the SQL ID of the problematic query from the AWR report and use it to trace the query in xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-completed-req[completed_requests]. + +* **Analyzing Performance**: +When rolling out changes, such as introducing new microservices, AWR lets you compare query performance before and after the update. +This helps you identify affected queries and optimize their performance accordingly. + +* **Analyzing Upgrade Impacts**: +You can assess query performance before and after a cluster upgrade to identify queries impacted by the new version. + +[#workload-repository] +== Workload Repository + +The workload repository is a centralized storage location where all snapshots are collected and maintained. +It is a user-defined location that can be a bucket or a collection, but not a scope. + +Before AWR can start collecting data, you must configure the repository location in the <> catalog. +Until this specified location is available, AWR remains in a quiescent (inactive) state. +Once the location becomes accessible, AWR transitions to an active state and begins collecting data. +If the location becomes unavailable at any point, AWR returns to the quiescent state and resumes activity only when the location is accessible again. + +For more information about setting up the repository location, see <>. + +[#snapshots] +== Snapshots + +AWR stores query performance data in the form of snapshots. +For each unique statement executed within a specified reporting interval, AWR generates a snapshot. +This snapshot contains aggregate metrics for all executions of that statement during the interval. +These metrics include execution time, CPU usage, memory consumption, and other performance indicators. + +Snapshots are stored as individual documents in the workload repository. +Each document is uniquely identified by its document key (ID), that includes the start time of the reporting interval, making it easier to filter and analyze data. + +=== Snapshot Retention Management + +To facilitate long-term analysis and performance comparisons across different periods, AWR retains snapshot documents in the repository. +By default, AWR does not automatically enforce retention policies on these documents. +Instead, you need to configure a Time-To-Live (TTL) or expiration for the AWR location. +The TTL specifies how long the documents remain in that location before the system automatically purges them. + +For example, setting a TTL of 180 days on a given bucket ensures that all snapshot documents older than 180 days within the bucket are automatically deleted. +This mechanism allows you to manage storage usage effectively while retaining relevant history of query performance data. +For more information about configuring the TTL, see xref:server:learn:data/expiration.adoc[Expiration]. + +[#enable-configure-awr] +== Enable and Configure AWR + +AWR is an opt-in feature that you must explicitly enable and configure. +Once enabled, AWR starts collecting data as soon as the repository location is set and is available. + +You can manage these settings through the <> catalog. + +[#system-awr] +=== system:awr + +This catalog determines how AWR functions including where it stores snapshots, how often it collects statistics, and which queries to include in the report. +You can adjust the AWR settings at any time to align with your monitoring needs. + +NOTE: Only admins or users with the `query_manage_system_catalog` role can modify settings in `system:awr`. +For more information, see xref:n1ql:n1ql-intro/sysinfo.adoc#authentication-and-client-privileges[Authentication and Client Privileges]. + +The catalog consists of the following attributes: + +[cols="1a,4a,1a"] +|=== +| Name | Description | Schema + +|**enabled** + +| Indicates whether AWR is enabled or disabled. + +*Default*: `FALSE` + +| Boolean + +| **location** + +| The target keyspace (repository) where the snapshots are stored. +This can only be a path to a bucket or collection; it cannot be a scope. +For more information about the repository, see <>. + +AWR checks the availability of the location only once per interval. + +*Example*: `"bucket1.scope1.collection1"` + +| String + +|**interval** + +|The duration of the reporting interval. +That is, the time between each snapshot collection. +If the interval is set to 10 minutes, AWR captures snapshots every 10 minutes. + +The interval must be at least 1 minute. + +*Default*: `"10m0s"` + +**Example**: `"1m30s"` + +|String (duration) + +|**threshold** + +|The minimum time a statement must take to complete for it be captured and included in the snapshot. + +The threshold must be at least 0 seconds. + +*Default*: `"0s"`, so that by default, all statements are captured by AWR regardless of their execution time. + +**Example**: `"1m30s"` +|String (duration) + +| **num_statements** + +| The maximum number of unique statements for which aggregate data is collected during each interval. + +Once the specified limit is reached during a reporting interval, AWR does not generate snapshots for any additional unique statements within that same interval. + +*Default*: `10000` + +*Max*: `100000` + +| Positive integer + +| **queue_len** + +| Length of the processing queue. +It is recommended not to change this value. + +The default value and maximum allowable value for `queue_len` are internally calculated based on system resources. + +| Positive integer +|=== + +=== Examples + +.Enable AWR and set the repository location +==== +The following query enables AWR and sets the repository location to `default.s1.awr`. +It also sets the reporting interval to 1 minute and threshold to 0 seconds. + +[source,sqlpp] +---- +UPDATE system:awr SET enabled = true, location = "default.s1.awr", +interval = "1m", threshold = "0s"; +---- +==== + +.Retrieve current AWR settings +==== +The following query retrieves the current AWR configuration settings. +[source,sqlpp] +---- +SELECT * FROM system:awr; +---- +==== + +[#monitor-awr] +== Monitor AWR + +The current status of AWR is recorded in the `query.log`. +You can view this information in the xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#vitals[system:vitals] output by using the following query: + +[source,sqlpp] +---- +SELECT awr FROM system:vitals; +---- + +[#view-awr-data-and-reports] +== View AWR Data and Reports + +You can access the AWR data by: + +* <> +* <> + +[#report-generation-tool] +=== Report Generation Tool + +You can generate AWR reports using Couchbase's `cbqueryreportgen` tool. +It provides comprehensive and user-friendly reports by executing SQL++ queries against the collected AWR data. + +For optimal query performance with the this tool, it is recommended to create an index on the document key (`META().id`) in your configured AWR location. +If this index is not present, the tool will use sequential scans, which can impact performance. + +For example, if the snapshots are stored in the `default:bucket1.scope1.awr` keyspace, you can create the recommended index as follows: + +[source,sqlpp] +---- +CREATE INDEX idx_awr ON default:bucket1.scope1.awr(META().id); +---- + +This index enables the `cbqueryreportgen` tool to efficiently query and retrieve AWR data for generating reports. +//For more information about the tool and its usage, see cbqueryreportgen. +// TODO: Add link to the CLI Reference section. + +[#query-awr-data-directly] +=== Querying AWR Data Directly + +You can also query AWR data directly from the workload repository using SQL++ queries. +When doing so, it is important to understand the data format, which is optimized to minimize the storage size. + +To query AWR data, access the specific target keyspace where the snapshots are stored. +The document keys (IDs) of the snapshot documents include the timestamp of the reporting interval's start time. +This allows you to filter documents based on time ranges without requiring additional indexes, as sequential scans support range-based key patterns. +However, if needed, you can define and add indexes to further optimize your queries. + +Each document contains the following fields: + +[cols="1a,4a,1a"] +|=== +| Name | Description | Schema + +| **cnt** + +| The number of times the statement was executed. +| Number + +| **from** + +| The start time of the interval, represented as an Epoch timestamp in milliseconds. +| Number + +| **to** + +|The end time of the interval, represented as an Epoch timestamp in milliseconds. +| Number + +| **pln** + +|An array containing the encoded, compressed outlines of the execution plan for both the minimum and maximum execution times of the statement. + +This is just the outline of the plan listing operators and significant objects used. +For full execution details, configure the xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-completed-config[completed_requests] system keyspace to capture the executions of the statement. + +You can use xref:n1ql:n1ql-language-reference/stringfun.adoc#fn-str-uncompress[UNCOMPRESS()] to decompress the execution plan strings, and then pass them to xref:n1ql:n1ql-language-reference/jsonfun.adoc[DECODE_JSON()] for formatting, if needed. + +| Array of strings + +| **qc** + +| The query context value. +| String + +| **sqlID** + +| The unique hash identifier of the statement. + +This can be used to aggregate information across different reporting periods for the same statement. +It is also included in the xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc#sys-completed-req[completed_requests] entries (collected independently of AWR). +| String + +| **sts** + +| An ordered array of 51 entries representing the total, min, and max values of 17 statistics. +That is, each statistic is represented by three consecutive entries in the array: the total value, the minimum value, and the maximum value. +These values have fixed array positions and appear in the sequence specified in the <> array. + +For example, the second statistic in the list is the CPU time. Therefore, + +-- +* `sts[3]` represents the total CPU time. +* `sts[4]` represents minimum CPU time. +* `sts[5]` represents the maximum CPU time. +-- +|<> array + +|**txt** + +| The statement text, possibly in a compressed format. + +Typically, this field is accessed using the xref:n1ql:n1ql-language-reference/stringfun.adoc#fn-str-uncompress[UNCOMPRESS()] function, and the function returns the raw text if it isn't compressed. + +| String + +|**ver** + +| The version of the data record. + +For this release, the value is always 1. + +| Number + +|=== + +[[Stats]] +==== Statistics +[cols="1a,4a,1a"] +|=== +| Name | Description | Schema + +| **total time** + +| The total time taken for the request, that is the time from when the request was received until the results were returned. + +It includes time spent in the queue and is analogous to `elapsedTime` in the xref:n1ql-rest-query:index.adoc#Metrics[Query REST API] response. + +| Number + +| **cpu time** + +| The amount of time the operators in the execution plan spent executing operator code. + +It is analogous to `cpuTime` in the xref:n1ql-rest-query:index.adoc#Metrics[Query Service API] response when xref:n1ql-rest-query:index.adoc#Profile[profiling] is enabled. + +| Number + +| **memory usage (quota)** + + +|The amount of document memory used to execute the request. +A request will return its document memory usage only if `memory-quota` is set for the query, or if both `node-quota` and `node-quota-val-percent` are set. +For more information about these settings, see xref:n1ql:n1ql-manage/query-settings.adoc[]. + +It is analogous to `usedMemory` in the xref:n1ql-rest-query:index.adoc#Metrics[Query Service API] response. + +| Number + + +| **result count** + +| The total number of objects in the results. + +It is analogous to `resultCount` in the xref:n1ql-rest-query:index.adoc#Metrics[Query Service API] response. +| Number + + +| **result size** + +|The total number of bytes in the results. + +It is analogous to `resultSize` in the xref:n1ql-rest-query:index.adoc#Metrics[Query Service API] response. +| Number + + +| **error count** + +| The number of errors that occurred during the request. + +It is analogous to `errorCount` in the xref:n1ql-rest-query:index.adoc#Metrics[Query Service API] response. +| Number + + +| **run time** + +| The total amount of time taken to execute the query. It does not include time spent in the queue. +| Number + + +| **fetch time** + +| The total amount of time spent fetching data from the Data service. + +It includes the time spent executing `Fetch` operator code and waiting for data from the Data service. +| Number + + +| **primary scan time** + +| The total amount of time spent by primary scan operations. + +It includes the time spent executing the `PrimaryScan` operator code and waiting for data from the Index service. +| Number + + +| **sequential scan time** + +| The amount of time spent by sequential scan operations. + +It includes the time spent executing the `PrimaryScan` operator code and waiting for data from the Data service. +| Number + + +| **primary scan count** + +| The total number of index keys returned by primary index scans and processed by the Query engine. +| Number + + +| **sequential scan count** + +| The total number of document keys returned by sequential scans and processed by the Query engine. +| Number + + +| **index scan count** + +| The total number of items returned by index scans and processed by the Query engine. +| Number + + +| **fetch count** + +| The total number of documents fetched from the Data service and processed by the Query engine. +| Number + +| **order count** + +| The number of items that were sorted. +| Number + + +| **primary scan ops** + +| The number of primary scan operators in the execution plan. +| Number + + +| **sequential scan ops** + +| The number of sequential scan operators in the execution plan. +| Number + +|=== + +=== Example +==== +The following example fetches AWR data for a specific SQL ID, including the statement text, max execution plan, number of executions, total time, and max CPU usage. + +.Query +[source,sqlpp] +---- +SELECT + text, + max_plan, + the_count, + avg_total_time, + max_cpu +FROM + default.s1.awr +LET + text = uncompress(txt) +WHERE + sqlID = 'fcff011269f93c3b7903d746c2914dab' +GROUP BY + sqlID, text +LETTING + the_count = SUM(cnt), + max_plan = json_decode(uncompress(MAX(pln[1]))), + avg_total_time = duration_to_str(SUM(sts[0])/SUM(cnt)), + max_cpu = duration_to_str(MAX(sts[5])); +---- + +.Result +[source,json] +---- +[ + { + "text": "select awr from system:vitals;", + "max_plan": { + "#operator": "Sequence", + "~children": [ + { + "#operator": "PrimaryScan", + "index_id": "#primary", + "keyspace": "vitals" + }, + { + "#operator": "Fetch", + "keyspace": "vitals" + }, + { + "#operator": "InitialProject" + }, + { + "#operator": "Stream" + } + ] + }, + "the_count": 2, + "avg_total_time": "38.844257ms", + "max_cpu": "193.409µs" + } +] +---- +==== + +== Limitations + +When working with Couchbase transactions, AWR collects performance statistics for all individual statements, and you may notice that the COMMIT statement often shows the highest elapsed time. +However, from the AWR report alone, you will not be able to get insights into why the COMMIT statement took so long to execute. \ No newline at end of file diff --git a/modules/n1ql/partials/nav.adoc b/modules/n1ql/partials/nav.adoc index 77ed75525..aa43f279e 100644 --- a/modules/n1ql/partials/nav.adoc +++ b/modules/n1ql/partials/nav.adoc @@ -37,6 +37,7 @@ *** xref:n1ql:n1ql-intro/sysinfo.adoc[] *** xref:tools:query-monitoring.adoc[] *** xref:n1ql:n1ql-manage/monitoring-n1ql-query.adoc[] + *** xref:n1ql:n1ql-manage/query-awr.adoc[] *** xref:manage:monitor/monitoring-indexes.adoc[] *** xref:manage:manage-indexes/manage-indexes.adoc[] *** xref:n1ql:n1ql-manage/query-settings.adoc[] From 4ba2851de8ebc2869f3cf5182bf9d843ea53ea82 Mon Sep 17 00:00:00 2001 From: Simon Dew <39966290+simon-dew@users.noreply.github.com> Date: Thu, 28 Aug 2025 12:44:22 +0100 Subject: [PATCH 14/14] DOC-13306: Add documentation for indexer level scan timeout (#399) * Replace Defer Index Builds example with link * Replace Indexer Scan Timeout example with link --- .../n1ql-language-reference/createindex.adoc | 21 ++----------------- .../pages/n1ql-language-reference/insert.adoc | 17 ++------------- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/modules/n1ql/pages/n1ql-language-reference/createindex.adoc b/modules/n1ql/pages/n1ql-language-reference/createindex.adoc index 5ed547d87..3ab6c8885 100644 --- a/modules/n1ql/pages/n1ql-language-reference/createindex.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/createindex.adoc @@ -440,25 +440,8 @@ In Couchbase Server 7.6.2 and later, you can change the default setting for the If you change the default setting for `defer_build` to `true`, index creation operates in deferred build mode by default. -To change the default setting for deferred builds, use the REST API to set the `indexer.settings.defer_build` property. -For example, - -[source,sh] ----- -curl http://$BASEURL:9102/settings -u $USER:$PASSWORD \ --d '{"indexer.settings.defer_build": true}' ----- - -Use the following command to retrieve the indexer settings: - -[source,sh] ----- -curl -X GET http://$BASEURL:9102/settings -u $USER:$PASSWORD ----- - -* `$BASEURL` is the base URL for the API call, for example: `localhost`. -* `$USER` is the username, for example: `Administrator`. -* `$PASSWORD` is the password. +To change the default setting for deferred builds, use the Index Settings REST API to set the `indexer.settings.defer_build` property. +For an example, see xref:index-rest-settings:index.adoc#ex-defer-build[Defer Index Builds by Default]. == Examples diff --git a/modules/n1ql/pages/n1ql-language-reference/insert.adoc b/modules/n1ql/pages/n1ql-language-reference/insert.adoc index 4e3d16961..9bfd3a57d 100644 --- a/modules/n1ql/pages/n1ql-language-reference/insert.adoc +++ b/modules/n1ql/pages/n1ql-language-reference/insert.adoc @@ -380,21 +380,8 @@ If you are inserting multiple documents, the statement aborts at the first error * Timeouts can affect the completion of an INSERT statement, especially when performing bulk inserts. Ensure that the timeout is set to a reasonable value that allows the bulk insert operation to complete. + -To set the indexer timeout, use the REST API to set the `indexer.settings.scan_timeout` property. -For example, -+ -[source,sh] ----- -curl http://localhost:9102/settings -u Administrator:password \ --d '{"indexer.settings.scan_timeout": 1200}' ----- -+ -Use the following command to retrieve the indexer settings: -+ -[source,sh] ----- -curl -X GET http://localhost:9102/settings -u Administrator:password ----- +To set the indexer timeout, use the Index Settings REST API to set the `indexer.settings.scan_timeout` property. +For an example, see xref:index-rest-settings:index.adoc#ex-scan-timeout[Set the Indexer Scan Timeout]. * When inserting multiple documents, no cleanup or rollback is done for the already inserted documents if the INSERT operations hits an error. This means, when you are inserting 10 documents, if the INSERT operation fails when inserting the 6th document, the operator quits and exits.