From 95a47ac9c46e87e059772dc3f8d478ee7a8c58bf Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Tue, 22 Oct 2024 20:47:17 +0530 Subject: [PATCH 01/29] Adding documentation for star tree index feature Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/index.md | 2 +- .../supported-field-types/star-tree.md | 148 +++++++++++++++ .../improving-search-performance.md | 4 +- _search-plugins/star-tree-index.md | 175 ++++++++++++++++++ images/star-tree-index.png | Bin 0 -> 159423 bytes 5 files changed, 327 insertions(+), 2 deletions(-) create mode 100644 _field-types/supported-field-types/star-tree.md create mode 100644 _search-plugins/star-tree-index.md create mode 100644 images/star-tree-index.png diff --git a/_field-types/supported-field-types/index.md b/_field-types/supported-field-types/index.md index a43da396d5..20e13cec7a 100644 --- a/_field-types/supported-field-types/index.md +++ b/_field-types/supported-field-types/index.md @@ -30,7 +30,7 @@ IP | [`ip`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/ip/): k-NN vector | [`knn_vector`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/knn-vector/): Allows indexing a k-NN vector into OpenSearch and performing different kinds of k-NN search. Percolator | [`percolator`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/percolator/): Specifies to treat this field as a query. Derived | [`derived`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/derived/): Creates new fields dynamically by executing scripts on existing fields. - +Star Tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Allows creating materialized views by pre-computing aggregations during indexing based on user-provided configuration to accelerate performance of aggregations. ## Arrays There is no dedicated array field type in OpenSearch. Instead, you can pass an array of values into any field. All values in the array must have the same field type. diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md new file mode 100644 index 0000000000..9ee40810c6 --- /dev/null +++ b/_field-types/supported-field-types/star-tree.md @@ -0,0 +1,148 @@ +--- +layout: default +title: Star Tree +nav_order: 61 +has_children: false +parent: Supported field types +redirect_from: + - /opensearch/supported-field-types/star-tree/ + - /field-types/star-tree/ +--- +# Star tree field type + +This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). +{: .warning} + +Star Tree Index is a multi-field index that improves the performance of aggregations. +Once you configure star-tree index as part of index mapping by specifying the dimensions and metrics, star-tree index gets created and maintained in real-time within segments as data is ingested. + +OpenSearch will automatically use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. + +For more information, see [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) + +## Prerequisites + +Before using star-tree field, be sure to satisfy the following prerequisites: + +- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). +- Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). +- Set the `index.composite_index` index setting to `true` during index creation. +- Enable `doc_values` : Ensure that the `doc_values` is enabled for the dimensions and metrics fields used in your star-tree mapping. + + +## Examples + +The following examples show how to use star-tree index. + +### Star tree index mapping + +Define star-tree mapping under new section `composite` in `mappings`.
+To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: + +```json +PUT logs +{ + "settings": { + "index.number_of_shards": 1, + "index.number_of_replicas": 0, + "index.composite_index": true + }, + "mappings": { + "composite": { + "startree1": { + "type": "star_tree", + "config": { + "max_leaf_docs": 10000, + "skip_star_node_creation_for_dimensions": [ + "port" + ], + "ordered_dimensions": [ + { + "name": "status" + }, + { + "name": "port" + } + ], + "metrics": [ + { + "name": "request_size", + "stats": [ + "sum", + "value_count", + "min", + "max" + ], + "name": "latency", + "stats": [ + "sum", + "value_count", + "min", + "max" + ] + } + ] + } + } + }, + "properties": { + "status": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "request_size": { + "type": "integer" + }, + "latency": { + "type": "scaled_float", + "scaling_factor": 10 + } + } + } +} +``` +In the above example, for `startree1` , we will create an associated Star Tree index. Currently only `one` star-tree index can be created per index with support for multiple star-trees coming in future.
+ +## Star tree mapping parameters +Specify star-tree configuration under `config` section. All parameters are final and cannot be modified without reindexing documents. + +### Ordered dimensions +The `ordered_dimensions` are fields based on which the metrics will be aggregated in star-tree index. Star Tree index will be picked for query optimizations only if all the fields in the query are part of the `ordered_dimensions`. This is a required property as part of star-tree configuration. +- The order of dimensions matter and you can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. +- Avoid high cardinality fields as dimensions , because it'll affect storage space, indexing throughput and query performance adversely. +- Currently, supported fields for `ordered_dimensions` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. + - Support for other field_types such as `keyword` , `ip` is coming as part of upcoming releases. +- Minimum of `2` and maximum of `10` dimensions are supported per Star Tree index. + +#### Properties + +| Parameter | Required/Optional | Description | +|:---------------------| :--- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `name` | Required | Name of the field which should also be present in `properties` as part of index `mapping` and ensure `doc_values` is `enabled` for associated fields. + +### Metrics +Configure fields for which you need to perform aggregations. This is required property as part of star-tree configuration. +- Currently, supported fields for `metrics` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. +- Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg` and `Value_count`. + - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest are base metrics which are indexed. +- Upto `100` base metrics are supported per Star Tree index. + +#### Properties + +| Parameter | Required/Optional | Description | +|:---------------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `name` | Required | Name of the field which should also be present in `properties` as part of index `mapping` and ensure `doc_values` is `enabled` for associated fields. +| `stats` | Optional | List of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Defaults are `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `sum` and `value_count` are present as part of metric `stats`. + +### Star tree configuration parameters +Following are additional optional parameters that can be configured alongside star-tree index. + +| Parameter | Required/Optional | Description | +|:----------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `max_leaf_docs` | Optional | The maximum number of star-tree documents leaf node can point to post which the nodes will be split to next dimension.10000 is the default value. Lowering the value will result in high storage size but faster query performance and the other way around when increasing the value. For more, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) +| `skip_star_node_creation_for_dimensions` | Optional | List of dimensions for which star-tree will skip creating star node. Setting this to `true` can reduce storage size at the expense of query performance. Default is false. To know more on star nodes, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) + +## Supported queries and aggregations +For more details on supported queries and aggregations, see [supported query and aggregations for Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-query-and-aggregations) diff --git a/_search-plugins/improving-search-performance.md b/_search-plugins/improving-search-performance.md index 4a0ffafe11..3172f0d925 100644 --- a/_search-plugins/improving-search-performance.md +++ b/_search-plugins/improving-search-performance.md @@ -11,4 +11,6 @@ OpenSearch offers several ways to improve search performance: - Run resource-intensive queries asynchronously with [asynchronous search]({{site.url}}{{site.baseurl}}/search-plugins/async/). -- Search segments concurrently using [concurrent segment search]({{site.url}}{{site.baseurl}}/search-plugins/concurrent-segment-search/). \ No newline at end of file +- Search segments concurrently using [concurrent segment search]({{site.url}}{{site.baseurl}}/search-plugins/concurrent-segment-search/). + +- Improve performance of aggregations using [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/). \ No newline at end of file diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md new file mode 100644 index 0000000000..528b59e2e2 --- /dev/null +++ b/_search-plugins/star-tree-index.md @@ -0,0 +1,175 @@ +--- +layout: default +title: Star Tree index +parent: Improving search performance +nav_order: 54 +--- + +# Star tree index + +This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). +{: .warning} + +Star Tree Index is a multi-field index that improves the performance of aggregations. + +OpenSearch will use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. + +## Star tree index structure + +A Star Tree index containing two dimensions and two metrics + +Star Tree index structure as portrayed in the above figure, consists of mainly two parts: Star Tree and sorted and aggregated star-tree documents backed by doc-values indexes. + +Each node in the Star Tree points to a range of star-tree documents. +A node is further split into child nodes based on [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/star-tree/#star-tree-configuration-parameters). +The number of documents a leaf node points to is than or equal to `max_leaf_docs`. This ensures the maximum number of documents that gets traversed to get to the aggregated value is at most `max_leaf_docs`, thus providing predictable latencies. + +There are special nodes called `star nodes (*)` which helps in skipping non-competitive nodes and also in fetching aggregated document wherever applicable during query time. + +The figure contains three examples explaining the Star Tree traversal during query: +- Compute average request size aggregation with Terms query where port equals 8443 and status equals 200 (Support for Terms query will be added in upcoming release) +- Compute count of requests aggregation with Term query where status equals 200 (query traverses through * node of `port` dimension since `port` is not present as part of query) +- Compute average request size aggregation with Term query where port equals 5600 (query traverses through * node of `status` dimension since `status` is not present as part of query). +
The second and third examples uses star nodes. + + +## When to use star tree index +You can be use Star Tree index to perform faster aggregations with a constant upper bound on query latency. +- Star Tree natively supports multi field aggregations +- Star Tree index will be created in real time as part of regular indexing, so the data in Star Tree will always be up to date with the live data. +- Star Tree index consolidates the data and hence is a storage efficient index which results in efficient paging and fraction of IO utilization for search queries. + +## Considerations +- Star Tree index ideally should be used with append-only indices, as updates or deletes are not accounted in Star Tree index. +- Star Tree index will be used for aggregation queries only if the query input is a subset of the Star Tree configuration of dimensions and metrics +- Once star-tree index is enabled for an index, you currently cannot disable it. You have to reindex without the star-tree mapping to remove star-tree from the index. + - Changing Star Tree configuration will also require a re-index operation. +- [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported +- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported with support for more coming in future +- The cardinality of the dimensions should not be very high (like "_id" fields), otherwise it leads to storage explosion and higher query latencies. + +## Enabling star tree index +- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). +- Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). +- Set the `index.composite_index` index setting to `true` during index creation. + +## Examples + +The following examples show how to use star-tree index. + +### Defining star tree index in mappings + +Define star-tree configuration in index mappings when creating an index.
+To create star-tree index to pre-compute aggregations for `request_size` and `latency` fields for all the combinations of values in `port` and `status` fields indexed in the `logs` index, configure the following mapping: + +```json +PUT logs +{ + "settings": { + "index.number_of_shards": 1, + "index.number_of_replicas": 0, + "index.composite_index": true + }, + "mappings": { + "composite": { + "startree1": { + "type": "star_tree", + "config": { + "ordered_dimensions": [ + { + "name": "status" + }, + { + "name": "port" + } + ], + "metrics": [ + { + "name": "request_size", + "stats": [ + "sum", + "value_count", + "min", + "max" + ], + "name": "latency", + "stats": [ + "sum", + "value_count", + "min", + "max" + ] + } + ] + } + } + }, + "properties": { + "status": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "request_size": { + "type": "integer" + }, + "latency": { + "type": "scaled_float", + "scaling_factor": 10 + } + } + } +} +``` + +For detailed information about Star Tree index mapping and parameters see [Star Tree field type]({{site.url}}{{site.baseurl}}/field-types/star-tree/). + +## Supported query and aggregations + +Star Tree index can be used to optimize aggregations for selected set of queries with support for more coming in upcoming releases. + +### Supported queries +Ensure the following in star tree index mapping, +- The fields present in the query must be present as part of `ordered_dimensions` as part of star-tree configuration. + +The following queries are supported [ when supported aggregations are specified ]
+ +- [Term query](https://opensearch.org/docs/latest/query-dsl/term/term/) +- [Match all docs query](https://opensearch.org/docs/latest/query-dsl/match-all/) + +### Supported aggregations +Ensure the following in star tree index mapping, +- The fields present in the aggregation must be present as part of `metrics` as part of star-tree configuration. +- The metric aggregation type must be part of `stats` parameter. + +Following metric aggregations are supported. +- [Sum](https://opensearch.org/docs/latest/aggregations/metric/sum/) +- [Minimum](https://opensearch.org/docs/latest/aggregations/metric/minimum/) +- [Maximum](https://opensearch.org/docs/latest/aggregations/metric/maximum/) +- [Value count](https://opensearch.org/docs/latest/aggregations/metric/value-count/) +- [Average](https://opensearch.org/docs/latest/aggregations/metric/average/) + +### Examples +To get sum of `request_size` for all error logs with `status=500` with the [example mapping](#defining-star-tree-index-in-mappings) : +```json +POST /logs/_search +{ + "query": { + "term": { + "status": "500" + } + }, + "aggs": { + "sum_request_size": { + "sum": { + "field": "request_size" + } + } + } +} +``` + +This query will get optimized automatically as star-tree index will be used. + +You can set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using star-tree index. \ No newline at end of file diff --git a/images/star-tree-index.png b/images/star-tree-index.png new file mode 100644 index 0000000000000000000000000000000000000000..f281ea84ac4c76cc5496438bcd91ca5c2d756f3a GIT binary patch literal 159423 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 literal 0 HcmV?d00001 From 78b4c414b859340442f88b05b539c50b4f29e0d0 Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Wed, 23 Oct 2024 15:42:41 +0530 Subject: [PATCH 02/29] addressing comments Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/index.md | 2 +- _field-types/supported-field-types/star-tree.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_field-types/supported-field-types/index.md b/_field-types/supported-field-types/index.md index 20e13cec7a..d1a498cef2 100644 --- a/_field-types/supported-field-types/index.md +++ b/_field-types/supported-field-types/index.md @@ -30,7 +30,7 @@ IP | [`ip`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/ip/): k-NN vector | [`knn_vector`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/knn-vector/): Allows indexing a k-NN vector into OpenSearch and performing different kinds of k-NN search. Percolator | [`percolator`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/percolator/): Specifies to treat this field as a query. Derived | [`derived`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/derived/): Creates new fields dynamically by executing scripts on existing fields. -Star Tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Allows creating materialized views by pre-computing aggregations during indexing based on user-provided configuration to accelerate performance of aggregations. +Star Tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Creates materialized views by pre-computing aggregations using star-tree index to accelerate performance of aggregations. ## Arrays There is no dedicated array field type in OpenSearch. Instead, you can pass an array of values into any field. All values in the array must have the same field type. diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 9ee40810c6..47eacc7fc4 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -13,8 +13,8 @@ redirect_from: This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index is a multi-field index that improves the performance of aggregations. -Once you configure star-tree index as part of index mapping by specifying the dimensions and metrics, star-tree index gets created and maintained in real-time within segments as data is ingested. +Star Tree Index is a multi-field index that improves the performance of aggregations by pre-computing the aggregations. +Once you configure star-tree index as part of index mapping, it will be created and maintained in real-time within segments as data is ingested. OpenSearch will automatically use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. @@ -27,7 +27,7 @@ Before using star-tree field, be sure to satisfy the following prerequisites: - Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. -- Enable `doc_values` : Ensure that the `doc_values` is enabled for the dimensions and metrics fields used in your star-tree mapping. +- Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your star-tree mapping. ## Examples From 0e0483a8147b3d41f6199004677f7911eea0d646 Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Wed, 23 Oct 2024 16:19:25 +0530 Subject: [PATCH 03/29] addressing comments Signed-off-by: Bharathwaj G --- .../supported-field-types/star-tree.md | 30 ++++++++++++++++++- _search-plugins/star-tree-index.md | 6 ++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 47eacc7fc4..1cf00e2bb4 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -129,6 +129,34 @@ Configure fields for which you need to perform aggregations. This is required pr - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest are base metrics which are indexed. - Upto `100` base metrics are supported per Star Tree index. +For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as part of all fields as part of `metrics` configuration, you can provide upto 25 fields as below +```json +{ +"metrics": [ + { + "name": "field1", + "stats": [ + "sum", + "value_count", + "min", + "max" + ], + ..., + ..., + "name": "field25", + "stats": [ + "sum", + "value_count", + "min", + "max" + ] + } +] + + +``` + + #### Properties | Parameter | Required/Optional | Description | @@ -137,7 +165,7 @@ Configure fields for which you need to perform aggregations. This is required pr | `stats` | Optional | List of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Defaults are `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `sum` and `value_count` are present as part of metric `stats`. ### Star tree configuration parameters -Following are additional optional parameters that can be configured alongside star-tree index. +Following are additional optional parameters that can be configured alongside star-tree index. These are final and cannot be modified post index creation. | Parameter | Required/Optional | Description | |:----------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 528b59e2e2..c9c7e8b507 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -40,13 +40,13 @@ You can be use Star Tree index to perform faster aggregations with a constant up - Star Tree index consolidates the data and hence is a storage efficient index which results in efficient paging and fraction of IO utilization for search queries. ## Considerations -- Star Tree index ideally should be used with append-only indices, as updates or deletes are not accounted in Star Tree index. +- Star Tree index ideally should be used with append-only indexes, as updates or deletes are not accounted in Star Tree index. - Star Tree index will be used for aggregation queries only if the query input is a subset of the Star Tree configuration of dimensions and metrics - Once star-tree index is enabled for an index, you currently cannot disable it. You have to reindex without the star-tree mapping to remove star-tree from the index. - Changing Star Tree configuration will also require a re-index operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported - Only [limited queries and aggregations](#supported-query-and-aggregations) are supported with support for more coming in future -- The cardinality of the dimensions should not be very high (like "_id" fields), otherwise it leads to storage explosion and higher query latencies. +- The cardinality of the dimensions should not be very high (like `_id` fields), otherwise it leads to storage explosion and higher query latencies. ## Enabling star tree index - Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). @@ -171,5 +171,7 @@ POST /logs/_search ``` This query will get optimized automatically as star-tree index will be used. +
With star-tree index, we will be able to retrieve the result with a single aggregated document once we traverse to the `status=500` node as opposed to scanning through all documents and perform summation as done currently in the regular query. +
This will result in lower query latency. You can set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using star-tree index. \ No newline at end of file From dcf47cfe8ce1302c285e768f0e11865e4aafb4ea Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Wed, 23 Oct 2024 18:15:45 +0530 Subject: [PATCH 04/29] fixes and addressing comments Signed-off-by: Bharathwaj G --- .../supported-field-types/star-tree.md | 2 +- _search-plugins/star-tree-index.md | 20 ++++++++---------- images/star-tree-index.png | Bin 159423 -> 158726 bytes 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 1cf00e2bb4..d9cd00da48 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -13,7 +13,7 @@ redirect_from: This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index is a multi-field index that improves the performance of aggregations by pre-computing the aggregations. +Star Tree Index creates materialized views by pre-computing aggregations to accelerate the performance of aggregations. Once you configure star-tree index as part of index mapping, it will be created and maintained in real-time within segments as data is ingested. OpenSearch will automatically use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index c9c7e8b507..1a61b90837 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -18,7 +18,11 @@ OpenSearch will use the star-tree index to optimize aggregations based on the in A Star Tree index containing two dimensions and two metrics -Star Tree index structure as portrayed in the above figure, consists of mainly two parts: Star Tree and sorted and aggregated star-tree documents backed by doc-values indexes. +Star Tree index structure as portrayed in the above figure, consists of mainly two parts: +- Star Tree and +- Sorted and aggregated star-tree documents backed by doc-values indexes + - The values are sorted based on the order of `ordered_dimension` , in the above example, first by `status` and then by `port` for each of the status. + - For each of the unique dimension values combinations , we also pre-compute the aggregated values for all the metrics such as `avg(size)` and `count(requests)` Each node in the Star Tree points to a range of star-tree documents. A node is further split into child nodes based on [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/star-tree/#star-tree-configuration-parameters). @@ -85,19 +89,13 @@ PUT logs ], "metrics": [ { - "name": "request_size", + "name": "size", "stats": [ - "sum", - "value_count", - "min", - "max" + "sum" ], "name": "latency", "stats": [ - "sum", - "value_count", - "min", - "max" + "avg" ] } ] @@ -111,7 +109,7 @@ PUT logs "port": { "type": "integer" }, - "request_size": { + "size": { "type": "integer" }, "latency": { diff --git a/images/star-tree-index.png b/images/star-tree-index.png index f281ea84ac4c76cc5496438bcd91ca5c2d756f3a..81309e1195fda13b282ea7744396670380f50f31 100644 GIT binary patch literal 158726 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 From 8ecd47309ad7de2a763eb76baf05eb045320ea64 Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Wed, 23 Oct 2024 19:51:26 +0530 Subject: [PATCH 05/29] addressing comments Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/index.md | 3 ++- _field-types/supported-field-types/star-tree.md | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/_field-types/supported-field-types/index.md b/_field-types/supported-field-types/index.md index d1a498cef2..d55cc03eb6 100644 --- a/_field-types/supported-field-types/index.md +++ b/_field-types/supported-field-types/index.md @@ -30,7 +30,8 @@ IP | [`ip`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/ip/): k-NN vector | [`knn_vector`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/knn-vector/): Allows indexing a k-NN vector into OpenSearch and performing different kinds of k-NN search. Percolator | [`percolator`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/percolator/): Specifies to treat this field as a query. Derived | [`derived`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/derived/): Creates new fields dynamically by executing scripts on existing fields. -Star Tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Creates materialized views by pre-computing aggregations using star-tree index to accelerate performance of aggregations. +Star Tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Pre-computes aggregations and stores in a Star Tree Index to accelerate the performance of aggregation queries. + ## Arrays There is no dedicated array field type in OpenSearch. Instead, you can pass an array of values into any field. All values in the array must have the same field type. diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index d9cd00da48..4c9f9fb7bf 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -13,7 +13,7 @@ redirect_from: This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index creates materialized views by pre-computing aggregations to accelerate the performance of aggregations. +Star Tree Index (STIX) pre-computes aggregations to accelerate the performance of aggregation queries. Once you configure star-tree index as part of index mapping, it will be created and maintained in real-time within segments as data is ingested. OpenSearch will automatically use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. @@ -127,9 +127,9 @@ Configure fields for which you need to perform aggregations. This is required pr - Currently, supported fields for `metrics` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. - Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg` and `Value_count`. - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest are base metrics which are indexed. -- Upto `100` base metrics are supported per Star Tree index. +- Maximum of `100` base metrics are supported per Star Tree index. -For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as part of all fields as part of `metrics` configuration, you can provide upto 25 fields as below +For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as part of all fields as part of `metrics` configuration, you can provide up to 25 fields as below ```json { "metrics": [ From d8357aeffc2b5bead7be405263b10aa6cf28f80d Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Thu, 24 Oct 2024 09:22:36 +0530 Subject: [PATCH 06/29] addressing comments Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/star-tree.md | 6 +++--- _search-plugins/star-tree-index.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 4c9f9fb7bf..b5828dd2df 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -112,7 +112,7 @@ Specify star-tree configuration under `config` section. All parameters are final The `ordered_dimensions` are fields based on which the metrics will be aggregated in star-tree index. Star Tree index will be picked for query optimizations only if all the fields in the query are part of the `ordered_dimensions`. This is a required property as part of star-tree configuration. - The order of dimensions matter and you can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. - Avoid high cardinality fields as dimensions , because it'll affect storage space, indexing throughput and query performance adversely. -- Currently, supported fields for `ordered_dimensions` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. +- Currently, supported fields for `ordered_dimensions` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`(see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). - Support for other field_types such as `keyword` , `ip` is coming as part of upcoming releases. - Minimum of `2` and maximum of `10` dimensions are supported per Star Tree index. @@ -124,9 +124,9 @@ The `ordered_dimensions` are fields based on which the metrics will be aggregate ### Metrics Configure fields for which you need to perform aggregations. This is required property as part of star-tree configuration. -- Currently, supported fields for `metrics` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. +- Currently, supported fields for `metrics` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long` (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). - Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg` and `Value_count`. - - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest are base metrics which are indexed. + - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest of the base metrics are indexed. - Maximum of `100` base metrics are supported per Star Tree index. For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as part of all fields as part of `metrics` configuration, you can provide up to 25 fields as below diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 1a61b90837..66057fa619 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -169,7 +169,7 @@ POST /logs/_search ``` This query will get optimized automatically as star-tree index will be used. -
With star-tree index, we will be able to retrieve the result with a single aggregated document once we traverse to the `status=500` node as opposed to scanning through all documents and perform summation as done currently in the regular query. +
With star-tree index, we will be able to retrieve the result with a single aggregated document once we traverse to the `status=500` node as opposed to current query execution which scans through all matching documents and perform summation.
This will result in lower query latency. You can set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using star-tree index. \ No newline at end of file From ffdc6dceb7651c554bef4de30c0cf1cb4586f19a Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Thu, 24 Oct 2024 18:05:03 +0530 Subject: [PATCH 07/29] addressing comments Signed-off-by: Bharathwaj G --- .../supported-field-types/star-tree.md | 41 ++++++------- _search-plugins/star-tree-index.md | 61 ++++++++++--------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index b5828dd2df..2fa5b301a6 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -13,30 +13,29 @@ redirect_from: This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index (STIX) pre-computes aggregations to accelerate the performance of aggregation queries. -Once you configure star-tree index as part of index mapping, it will be created and maintained in real-time within segments as data is ingested. - -OpenSearch will automatically use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. +Star Tree Index (STIX) pre-computes aggregations to accelerate the performance of aggregation queries.
+If STIX is configured as part of index mapping, it will be created and maintained in real-time as the data is ingested.
+OpenSearch will automatically use the Star Tree index to optimize aggregations if the fields queried are part of Star Tree's dimension fields and the aggregations are on Star Tree's metrics fields. No changes are required in the query syntax or the request parameters. For more information, see [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) ## Prerequisites -Before using star-tree field, be sure to satisfy the following prerequisites: +To use Star Tree on your index, the following prerequisites needs to be satisfied: - Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). -- Set the `index.composite_index` index setting to `true` during index creation. -- Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your star-tree mapping. - +- Set the `index.composite_index` index setting to `true` during index creation. +- Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your Star Tree mapping. +- Star Tree index ideally should be used with indices whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. ## Examples -The following examples show how to use star-tree index. +The following examples show how to use Star Tree index. ### Star tree index mapping -Define star-tree mapping under new section `composite` in `mappings`.
+Define Star Tree mapping under new section `composite` in `mappings`.
To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: ```json @@ -103,17 +102,17 @@ PUT logs } } ``` -In the above example, for `startree1` , we will create an associated Star Tree index. Currently only `one` star-tree index can be created per index with support for multiple star-trees coming in future.
+In the above example, for `startree1` , we will create an associated Star Tree index. Currently only `one` Star Tree index can be created per index. Support for multiple Star Trees is a work in progress and will be released in the future.
## Star tree mapping parameters -Specify star-tree configuration under `config` section. All parameters are final and cannot be modified without reindexing documents. +Specify Star Tree configuration under `config` section. All parameters are final and cannot be modified without reindexing documents. ### Ordered dimensions -The `ordered_dimensions` are fields based on which the metrics will be aggregated in star-tree index. Star Tree index will be picked for query optimizations only if all the fields in the query are part of the `ordered_dimensions`. This is a required property as part of star-tree configuration. +The `ordered_dimensions` are fields based on which the metrics will be aggregated in a Star Tree index. Star Tree index will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. - The order of dimensions matter and you can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. -- Avoid high cardinality fields as dimensions , because it'll affect storage space, indexing throughput and query performance adversely. +- Avoid high cardinality fields as dimensions as it'll affect storage space, indexing throughput and query performance adversely. - Currently, supported fields for `ordered_dimensions` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`(see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). - - Support for other field_types such as `keyword` , `ip` is coming as part of upcoming releases. + - Support for other field_types such as `keyword`, `ip` is currently work in progress and will be released in future versions (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/16232)) - Minimum of `2` and maximum of `10` dimensions are supported per Star Tree index. #### Properties @@ -123,13 +122,13 @@ The `ordered_dimensions` are fields based on which the metrics will be aggregate | `name` | Required | Name of the field which should also be present in `properties` as part of index `mapping` and ensure `doc_values` is `enabled` for associated fields. ### Metrics -Configure fields for which you need to perform aggregations. This is required property as part of star-tree configuration. +Configure fields for which you need to perform aggregations. This is required property as part of Star Tree configuration. - Currently, supported fields for `metrics` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long` (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). - Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg` and `Value_count`. - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest of the base metrics are indexed. - Maximum of `100` base metrics are supported per Star Tree index. -For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as part of all fields as part of `metrics` configuration, you can provide up to 25 fields as below +For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as `metrics` for each field. Then, you can provide up to 25 fields as below. ```json { "metrics": [ @@ -162,15 +161,15 @@ For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as part of al | Parameter | Required/Optional | Description | |:---------------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `name` | Required | Name of the field which should also be present in `properties` as part of index `mapping` and ensure `doc_values` is `enabled` for associated fields. -| `stats` | Optional | List of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Defaults are `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `sum` and `value_count` are present as part of metric `stats`. +| `stats` | Optional | List of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Defaults are `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `Sum` and `Value_Count` are present as part of metric `stats`. ### Star tree configuration parameters -Following are additional optional parameters that can be configured alongside star-tree index. These are final and cannot be modified post index creation. +Following are additional optional parameters that can be configured alongside Star Tree index. These are final and cannot be modified post index creation. | Parameter | Required/Optional | Description | |:----------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `max_leaf_docs` | Optional | The maximum number of star-tree documents leaf node can point to post which the nodes will be split to next dimension.10000 is the default value. Lowering the value will result in high storage size but faster query performance and the other way around when increasing the value. For more, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) -| `skip_star_node_creation_for_dimensions` | Optional | List of dimensions for which star-tree will skip creating star node. Setting this to `true` can reduce storage size at the expense of query performance. Default is false. To know more on star nodes, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) +| `max_leaf_docs` | Optional | The maximum number of Star Tree documents leaf node can point to post which the nodes will be split to next dimension.10000 is the default value. Lowering the value will result in high storage size but faster query performance and the other way around when increasing the value. For more, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) +| `skip_star_node_creation_for_dimensions` | Optional | List of dimensions for which Star Tree will skip creating star node. Setting this to `true` can reduce storage size at the expense of query performance. Default is false. To know more on star nodes, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) ## Supported queries and aggregations For more details on supported queries and aggregations, see [supported query and aggregations for Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-query-and-aggregations) diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 66057fa619..bd1f33202f 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -12,7 +12,7 @@ This is an experimental feature and is not recommended for use in a production e Star Tree Index is a multi-field index that improves the performance of aggregations. -OpenSearch will use the star-tree index to optimize aggregations based on the input query and star-tree configuration. No changes are required in the query syntax or requests. +OpenSearch will automatically use the Star Tree index to optimize aggregations if the fields queried are part of Star Tree's dimension fields and the aggregations are on Star Tree's metrics fields. No changes are required in the query syntax or the request parameters. ## Star tree index structure @@ -20,37 +20,37 @@ OpenSearch will use the star-tree index to optimize aggregations based on the in Star Tree index structure as portrayed in the above figure, consists of mainly two parts: - Star Tree and -- Sorted and aggregated star-tree documents backed by doc-values indexes - - The values are sorted based on the order of `ordered_dimension` , in the above example, first by `status` and then by `port` for each of the status. - - For each of the unique dimension values combinations , we also pre-compute the aggregated values for all the metrics such as `avg(size)` and `count(requests)` +- Sorted and aggregated Star Tree documents backed by doc-values indexes + - The values are sorted based on the order of `ordered_dimension`, in the above example, first by `status` and then by `port` for each of the status. + - For each of the unique dimension value combinations, the aggregated values for all the metrics such as `avg(size)` and `count(requests)` are pre-computed during ingestion time. -Each node in the Star Tree points to a range of star-tree documents. +Each node in the Star Tree points to a range of Star Tree documents. A node is further split into child nodes based on [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/star-tree/#star-tree-configuration-parameters). -The number of documents a leaf node points to is than or equal to `max_leaf_docs`. This ensures the maximum number of documents that gets traversed to get to the aggregated value is at most `max_leaf_docs`, thus providing predictable latencies. +The number of documents a leaf node points to is less than or equal to `max_leaf_docs`. This ensures the maximum number of documents that gets traversed to get to the aggregated value is at most `max_leaf_docs`, thus providing predictable latency. There are special nodes called `star nodes (*)` which helps in skipping non-competitive nodes and also in fetching aggregated document wherever applicable during query time. The figure contains three examples explaining the Star Tree traversal during query: -- Compute average request size aggregation with Terms query where port equals 8443 and status equals 200 (Support for Terms query will be added in upcoming release) +- Compute average request size aggregation with Terms query where port equals 8443 and status equals 200 (Support for Terms query will be added in upcoming release, see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15257)) - Compute count of requests aggregation with Term query where status equals 200 (query traverses through * node of `port` dimension since `port` is not present as part of query) - Compute average request size aggregation with Term query where port equals 5600 (query traverses through * node of `status` dimension since `status` is not present as part of query).
The second and third examples uses star nodes. ## When to use star tree index -You can be use Star Tree index to perform faster aggregations with a constant upper bound on query latency. +Star Tree index can be used to perform faster aggregations with a constant upper bound on query latency. - Star Tree natively supports multi field aggregations -- Star Tree index will be created in real time as part of regular indexing, so the data in Star Tree will always be up to date with the live data. -- Star Tree index consolidates the data and hence is a storage efficient index which results in efficient paging and fraction of IO utilization for search queries. +- Star Tree index will be created in real time as part of indexing, so the data in Star Tree will always be up to date. +- Star Tree index consolidates the data and hence it is storage efficient. It helps in efficient paging and lesser IO utilization for search queries. ## Considerations -- Star Tree index ideally should be used with append-only indexes, as updates or deletes are not accounted in Star Tree index. -- Star Tree index will be used for aggregation queries only if the query input is a subset of the Star Tree configuration of dimensions and metrics -- Once star-tree index is enabled for an index, you currently cannot disable it. You have to reindex without the star-tree mapping to remove star-tree from the index. +- Star Tree index ideally should be used with indices whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. +- Star Tree index will be used for aggregation queries only if the fields getting queried is a subset of the Star Tree's dimensions and fields getting aggregated is a subset of Start Tree's metrics +- Once Star Tree index is enabled for an index, it cannot be disabled. The data has to be re-indexed without the Star Tree mapping to remove Star Tree from the index. - Changing Star Tree configuration will also require a re-index operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported -- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported with support for more coming in future -- The cardinality of the dimensions should not be very high (like `_id` fields), otherwise it leads to storage explosion and higher query latencies. +- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported currently. Support for more features will be released in upcoming versions. +- The cardinality of the dimensions should not be very high (like `_id` fields), otherwise it leads to high storage usage and higher query latency. ## Enabling star tree index - Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). @@ -59,12 +59,12 @@ You can be use Star Tree index to perform faster aggregations with a constant up ## Examples -The following examples show how to use star-tree index. +The following examples show how to use Star Tree index. ### Defining star tree index in mappings -Define star-tree configuration in index mappings when creating an index.
-To create star-tree index to pre-compute aggregations for `request_size` and `latency` fields for all the combinations of values in `port` and `status` fields indexed in the `logs` index, configure the following mapping: +Define Star Tree configuration in index mappings when creating an index.
+To create Star Tree index to pre-compute aggregations for `request_size` and `latency` fields for all the combinations of values in `port` and `status` fields indexed in the `logs` index, configure the following mapping: ```json PUT logs @@ -125,29 +125,30 @@ For detailed information about Star Tree index mapping and parameters see [Star ## Supported query and aggregations -Star Tree index can be used to optimize aggregations for selected set of queries with support for more coming in upcoming releases. +Star Tree index can be used to optimize aggregations. The list of supported queries is given below, support for more queries will be added in upcoming releases (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15257)). ### Supported queries -Ensure the following in star tree index mapping, -- The fields present in the query must be present as part of `ordered_dimensions` as part of star-tree configuration. - -The following queries are supported [ when supported aggregations are specified ]
+The following queries are supported as of OpenSearch 2.18 [ when supported aggregations are specified ]
- [Term query](https://opensearch.org/docs/latest/query-dsl/term/term/) - [Match all docs query](https://opensearch.org/docs/latest/query-dsl/match-all/) -### Supported aggregations Ensure the following in star tree index mapping, -- The fields present in the aggregation must be present as part of `metrics` as part of star-tree configuration. -- The metric aggregation type must be part of `stats` parameter. +- The fields present in the query must be present as part of `ordered_dimensions` as part of Star Tree configuration. + +### Supported aggregations -Following metric aggregations are supported. +Following metric aggregations are supported as of OpenSearch 2.18. - [Sum](https://opensearch.org/docs/latest/aggregations/metric/sum/) - [Minimum](https://opensearch.org/docs/latest/aggregations/metric/minimum/) - [Maximum](https://opensearch.org/docs/latest/aggregations/metric/maximum/) - [Value count](https://opensearch.org/docs/latest/aggregations/metric/value-count/) - [Average](https://opensearch.org/docs/latest/aggregations/metric/average/) +Ensure the following in Star Tree index mapping, +- The fields present in the aggregation must be present as part of `metrics` as part of Star Tree configuration. +- The metric aggregation type must be part of `stats` parameter. + ### Examples To get sum of `request_size` for all error logs with `status=500` with the [example mapping](#defining-star-tree-index-in-mappings) : ```json @@ -168,8 +169,8 @@ POST /logs/_search } ``` -This query will get optimized automatically as star-tree index will be used. -
With star-tree index, we will be able to retrieve the result with a single aggregated document once we traverse to the `status=500` node as opposed to current query execution which scans through all matching documents and perform summation. +This query will get optimized automatically as Star Tree index will be used. +
With Star Tree index, the result will be retrieved from a single aggregated document as it traverses to the `status=500` node as opposed to current query execution which scans through all the matching documents and perform summation.
This will result in lower query latency. -You can set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using star-tree index. \ No newline at end of file +You can set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using Star Tree index. \ No newline at end of file From b3b578386f80fc8b5f9de68d437cdcbecf83f852 Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Thu, 24 Oct 2024 19:43:10 +0530 Subject: [PATCH 08/29] fixing json Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/star-tree.md | 4 +++- _search-plugins/star-tree-index.md | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 2fa5b301a6..53a3afdc0c 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -71,7 +71,9 @@ PUT logs "value_count", "min", "max" - ], + ] + }, + { "name": "latency", "stats": [ "sum", diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index bd1f33202f..36988e6b26 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -44,7 +44,7 @@ Star Tree index can be used to perform faster aggregations with a constant upper - Star Tree index consolidates the data and hence it is storage efficient. It helps in efficient paging and lesser IO utilization for search queries. ## Considerations -- Star Tree index ideally should be used with indices whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. +- Star Tree index ideally should be used with indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. - Star Tree index will be used for aggregation queries only if the fields getting queried is a subset of the Star Tree's dimensions and fields getting aggregated is a subset of Start Tree's metrics - Once Star Tree index is enabled for an index, it cannot be disabled. The data has to be re-indexed without the Star Tree mapping to remove Star Tree from the index. - Changing Star Tree configuration will also require a re-index operation. @@ -92,7 +92,9 @@ PUT logs "name": "size", "stats": [ "sum" - ], + ] + }, + { "name": "latency", "stats": [ "avg" From 05edca06bafbc2eeb81d5a14330383d8369b879c Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Thu, 24 Oct 2024 20:28:39 +0530 Subject: [PATCH 09/29] fixing json Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/star-tree.md | 2 +- _search-plugins/star-tree-index.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 53a3afdc0c..761fbdfd3d 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -27,7 +27,7 @@ To use Star Tree on your index, the following prerequisites needs to be satisfie - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. - Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your Star Tree mapping. -- Star Tree index ideally should be used with indices whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. +- Star Tree index ideally should be used with indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. ## Examples diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 36988e6b26..e21d942374 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -64,7 +64,7 @@ The following examples show how to use Star Tree index. ### Defining star tree index in mappings Define Star Tree configuration in index mappings when creating an index.
-To create Star Tree index to pre-compute aggregations for `request_size` and `latency` fields for all the combinations of values in `port` and `status` fields indexed in the `logs` index, configure the following mapping: +To create Star Tree index to pre-compute aggregations for `size` and `latency` fields for all the combinations of values in `port` and `status` fields indexed in the `logs` index, configure the following mapping: ```json PUT logs @@ -152,7 +152,7 @@ Ensure the following in Star Tree index mapping, - The metric aggregation type must be part of `stats` parameter. ### Examples -To get sum of `request_size` for all error logs with `status=500` with the [example mapping](#defining-star-tree-index-in-mappings) : +To get sum of `size` for all error logs with `status=500` with the [example mapping](#defining-star-tree-index-in-mappings) : ```json POST /logs/_search { @@ -162,9 +162,9 @@ POST /logs/_search } }, "aggs": { - "sum_request_size": { + "sum_size": { "sum": { - "field": "request_size" + "field": "size" } } } From 06848eb8d555a841590ac93de903465cfac60598 Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Tue, 29 Oct 2024 18:48:31 +0530 Subject: [PATCH 10/29] addressing comments Signed-off-by: Bharathwaj G --- .../supported-field-types/star-tree.md | 53 +++++++++---------- _search-plugins/star-tree-index.md | 6 +-- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 761fbdfd3d..586ad777d4 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -15,7 +15,7 @@ This is an experimental feature and is not recommended for use in a production e Star Tree Index (STIX) pre-computes aggregations to accelerate the performance of aggregation queries.
If STIX is configured as part of index mapping, it will be created and maintained in real-time as the data is ingested.
-OpenSearch will automatically use the Star Tree index to optimize aggregations if the fields queried are part of Star Tree's dimension fields and the aggregations are on Star Tree's metrics fields. No changes are required in the query syntax or the request parameters. +OpenSearch will automatically use the STIX to optimize aggregations if the fields queried are part of STIX dimension fields and the aggregations are on STIX metrics fields. No changes are required in the query syntax or the request parameters. For more information, see [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) @@ -27,7 +27,7 @@ To use Star Tree on your index, the following prerequisites needs to be satisfie - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. - Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your Star Tree mapping. -- Star Tree index ideally should be used with indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. +- STIX should only be used on indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in STIX. ## Examples @@ -104,13 +104,13 @@ PUT logs } } ``` -In the above example, for `startree1` , we will create an associated Star Tree index. Currently only `one` Star Tree index can be created per index. Support for multiple Star Trees is a work in progress and will be released in the future.
+In the above example, for `startree1` , it will create a corresponding STIX. Currently only `one` STIX can be created per index. Support for multiple Star Trees is a work in progress and will be released in the future.
## Star tree mapping parameters Specify Star Tree configuration under `config` section. All parameters are final and cannot be modified without reindexing documents. ### Ordered dimensions -The `ordered_dimensions` are fields based on which the metrics will be aggregated in a Star Tree index. Star Tree index will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. +The `ordered_dimensions` are fields based on which the metrics will be aggregated in a STIX. STIX will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. - The order of dimensions matter and you can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. - Avoid high cardinality fields as dimensions as it'll affect storage space, indexing throughput and query performance adversely. - Currently, supported fields for `ordered_dimensions` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`(see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). @@ -130,31 +130,30 @@ Configure fields for which you need to perform aggregations. This is required pr - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest of the base metrics are indexed. - Maximum of `100` base metrics are supported per Star Tree index. -For example, say you provide `Min`, `Max`, `Sum` and `Value_count` as `metrics` for each field. Then, you can provide up to 25 fields as below. +For example, if `Min`, `Max`, `Sum` and `Value_count` are defined as `metrics` for each field. Then, up to 25 such fields can be configured as below. ```json { -"metrics": [ - { - "name": "field1", - "stats": [ - "sum", - "value_count", - "min", - "max" - ], - ..., - ..., - "name": "field25", - "stats": [ - "sum", - "value_count", - "min", - "max" - ] - } -] - - + "metrics": [ + { + "name": "field1", + "stats": [ + "sum", + "value_count", + "min", + "max" + ], + ..., + ..., + "name": "field25", + "stats": [ + "sum", + "value_count", + "min", + "max" + ] + } + ] +} ``` diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index e21d942374..480617664a 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -10,9 +10,9 @@ nav_order: 54 This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index is a multi-field index that improves the performance of aggregations. +Star Tree Index (STIX) is a multi-field index that improves the performance of aggregations. -OpenSearch will automatically use the Star Tree index to optimize aggregations if the fields queried are part of Star Tree's dimension fields and the aggregations are on Star Tree's metrics fields. No changes are required in the query syntax or the request parameters. +OpenSearch will automatically use the STIX to optimize aggregations if the fields queried are part of STIX dimension fields and the aggregations are on STIX metrics fields. No changes are required in the query syntax or the request parameters. ## Star tree index structure @@ -44,7 +44,7 @@ Star Tree index can be used to perform faster aggregations with a constant upper - Star Tree index consolidates the data and hence it is storage efficient. It helps in efficient paging and lesser IO utilization for search queries. ## Considerations -- Star Tree index ideally should be used with indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in Star Tree index. +- STIX should only be used on indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in STIX. - Star Tree index will be used for aggregation queries only if the fields getting queried is a subset of the Star Tree's dimensions and fields getting aggregated is a subset of Start Tree's metrics - Once Star Tree index is enabled for an index, it cannot be disabled. The data has to be re-indexed without the Star Tree mapping to remove Star Tree from the index. - Changing Star Tree configuration will also require a re-index operation. From 5f51c3ad09f551b5ae371b563f92c2a820879ec7 Mon Sep 17 00:00:00 2001 From: Bharathwaj G Date: Tue, 29 Oct 2024 20:56:01 +0530 Subject: [PATCH 11/29] addressing comments Signed-off-by: Bharathwaj G --- _field-types/supported-field-types/star-tree.md | 4 ++-- _search-plugins/star-tree-index.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 586ad777d4..f8ae53a98a 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -48,7 +48,7 @@ PUT logs }, "mappings": { "composite": { - "startree1": { + "request_aggs": { "type": "star_tree", "config": { "max_leaf_docs": 10000, @@ -104,7 +104,7 @@ PUT logs } } ``` -In the above example, for `startree1` , it will create a corresponding STIX. Currently only `one` STIX can be created per index. Support for multiple Star Trees is a work in progress and will be released in the future.
+In the above example, for `request_aggs` , it will create a corresponding STIX. Currently only `one` STIX can be created per index. Support for multiple Star Trees is a work in progress and will be released in the future.
## Star tree mapping parameters Specify Star Tree configuration under `config` section. All parameters are final and cannot be modified without reindexing documents. diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 480617664a..2b40383e90 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -76,7 +76,7 @@ PUT logs }, "mappings": { "composite": { - "startree1": { + "request_aggs": { "type": "star_tree", "config": { "ordered_dimensions": [ From 759a258dd4cf8251ab49f05baa8577e4b0fc1a8f Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:21:37 -0500 Subject: [PATCH 12/29] Add edits for star tree field page Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- .../supported-field-types/star-tree.md | 113 +++++++++++------- 1 file changed, 70 insertions(+), 43 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index f8ae53a98a..d5fdf59d20 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -2,41 +2,46 @@ layout: default title: Star Tree nav_order: 61 -has_children: false parent: Supported field types -redirect_from: - - /opensearch/supported-field-types/star-tree/ - - /field-types/star-tree/ --- -# Star tree field type + +# Star-tree field type This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index (STIX) pre-computes aggregations to accelerate the performance of aggregation queries.
-If STIX is configured as part of index mapping, it will be created and maintained in real-time as the data is ingested.
-OpenSearch will automatically use the STIX to optimize aggregations if the fields queried are part of STIX dimension fields and the aggregations are on STIX metrics fields. No changes are required in the query syntax or the request parameters. +[Star-tree index](https://docs.pinot.apache.org/basics/indexing/star-tree-index) pre-computes aggregations, accelerating the performance of aggregation queries. +If a star-tree index is configured as part of an index mapping, the star-tree index is created and maintained as data is ingested in real time. + +OpenSearch will automatically use the star-tree index to optimize aggregations if the fields queried are part of star-tree index dimension fields and the aggregations are on star-tree index metrics fields. No changes are required in the query syntax or the request parameters. For more information, see [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) ## Prerequisites -To use Star Tree on your index, the following prerequisites needs to be satisfied: +To use the star-tree index, fulfill the following prerequisites: -- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). +- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. -- Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your Star Tree mapping. -- STIX should only be used on indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in STIX. +- Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your star-tree mapping. + +## Limitations + +The star-tree index feature has the following limitations: + +- A star-tree index should only be used on indexes whose data is not updated or deleted, as standard updates and deletions are not accounted in the star-tree index. +- Currently, only `one` star-tree index can be created per index. Support for multiple star-trees will be added in a future release. ## Examples -The following examples show how to use Star Tree index. +The following examples show how to use a star-tree index + +### Star0tree index mapping -### Star tree index mapping +Define Star Tree mapping under the `composite` section in `mappings`. -Define Star Tree mapping under new section `composite` in `mappings`.
-To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: +The following example creates a corresponding star-tree index for all `request_aggs`. To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: ```json PUT logs @@ -104,33 +109,51 @@ PUT logs } } ``` -In the above example, for `request_aggs` , it will create a corresponding STIX. Currently only `one` STIX can be created per index. Support for multiple Star Trees is a work in progress and will be released in the future.
+ + ## Star tree mapping parameters -Specify Star Tree configuration under `config` section. All parameters are final and cannot be modified without reindexing documents. + +Specify any star-tree configuration mapping options under the `config` section. All parameters are final and cannot be modified without reindexing documents. + +The star-tree `config` section supports the following property. + +| Parameter | Required/Optional | Description | +| :--- | :--- | :--- | +| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. ### Ordered dimensions -The `ordered_dimensions` are fields based on which the metrics will be aggregated in a STIX. STIX will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. -- The order of dimensions matter and you can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. -- Avoid high cardinality fields as dimensions as it'll affect storage space, indexing throughput and query performance adversely. -- Currently, supported fields for `ordered_dimensions` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`(see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). - - Support for other field_types such as `keyword`, `ip` is currently work in progress and will be released in future versions (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/16232)) -- Minimum of `2` and maximum of `10` dimensions are supported per Star Tree index. -#### Properties +The `ordered_dimensions` parameter are fields based on which metrics will be aggregated in a star-tree index. The star-tree index will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. + +When using the `ordered_dimesions` parameter, remember the following best practices: + +- The order of dimensions matter. You can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. +- Avoid high cardinality fields as dimensions. High cardinality fields adversely affect storage space, indexing throughput, and query performance. +- Currently, supported fields for `ordered_dimensions` are all [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. For more information, see [GitHub issue #15231](https://github.com/opensearch-project/OpenSearch/issues/15231). +- Support for other field_types such as `keyword`, `ip` will be released in future versions. For more information, see [GitHub issue #16232](https://github.com/opensearch-project/OpenSearch/issues/16232). +- A minimum of `2` and maximum of `10` dimensions are supported per star-tree index. + +`ordered_dimensions` supports the following property + +| Parameter | Required/Optional | Description | +| :--- | :--- | :--- | +| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. | -| Parameter | Required/Optional | Description | -|:---------------------| :--- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `name` | Required | Name of the field which should also be present in `properties` as part of index `mapping` and ensure `doc_values` is `enabled` for associated fields. ### Metrics -Configure fields for which you need to perform aggregations. This is required property as part of Star Tree configuration. -- Currently, supported fields for `metrics` are of [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long` (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15231)). + +Configure any metric fields for which you need to perform aggregations. `Metrics` are required as part of a star-tree configuration. + +When using `metrics`, remember the following best practices: + +- Currently, supported fields for `metrics` are all [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. For more information, see [GitHub issue #15231](https://github.com/opensearch-project/OpenSearch/issues/15231). - Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg` and `Value_count`. - - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest of the base metrics are indexed. -- Maximum of `100` base metrics are supported per Star Tree index. + - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest of the base metrics are indexed. +- A maximum of `100` base metrics are supported per star-tree index. + +If `Min`, `Max`, `Sum` and `Value_count` are defined as `metrics` for each field then up to 25 such fields can be configured, as shown in the following example: -For example, if `Min`, `Max`, `Sum` and `Value_count` are defined as `metrics` for each field. Then, up to 25 such fields can be configured as below. ```json { "metrics": [ @@ -159,18 +182,22 @@ For example, if `Min`, `Max`, `Sum` and `Value_count` are defined as `metrics` f #### Properties -| Parameter | Required/Optional | Description | -|:---------------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `name` | Required | Name of the field which should also be present in `properties` as part of index `mapping` and ensure `doc_values` is `enabled` for associated fields. -| `stats` | Optional | List of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Defaults are `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `Sum` and `Value_Count` are present as part of metric `stats`. +The `metrics` parameter supports the following properties: + +| Parameter | Required/Optional | Description | +| :--- | :--- | :--- | +| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. | +| `stats` | Optional | A list of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Default is `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `Sum` and `Value_Count` are present as part of metric `stats`. ### Star tree configuration parameters -Following are additional optional parameters that can be configured alongside Star Tree index. These are final and cannot be modified post index creation. -| Parameter | Required/Optional | Description | -|:----------------|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `max_leaf_docs` | Optional | The maximum number of Star Tree documents leaf node can point to post which the nodes will be split to next dimension.10000 is the default value. Lowering the value will result in high storage size but faster query performance and the other way around when increasing the value. For more, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) -| `skip_star_node_creation_for_dimensions` | Optional | List of dimensions for which Star Tree will skip creating star node. Setting this to `true` can reduce storage size at the expense of query performance. Default is false. To know more on star nodes, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) +The following optional parameters can be configured with a star-tree index. These are final and cannot be modified post index creation. + +| Parameter | Description | +| :--- | :--- | +| `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) | +| `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip creating the star node. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information on star nodes, see [star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) | ## Supported queries and aggregations -For more details on supported queries and aggregations, see [supported query and aggregations for Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-query-and-aggregations) + +For more details on supported queries and aggregations, see [supported query and aggregations for a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-query-and-aggregations). From db0e127a13f63fe74332fa0d290fabf189b403ef Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:23:23 -0500 Subject: [PATCH 13/29] Add index edit Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_field-types/supported-field-types/index.md b/_field-types/supported-field-types/index.md index d55cc03eb6..f97f2a1384 100644 --- a/_field-types/supported-field-types/index.md +++ b/_field-types/supported-field-types/index.md @@ -30,7 +30,7 @@ IP | [`ip`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/ip/): k-NN vector | [`knn_vector`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/knn-vector/): Allows indexing a k-NN vector into OpenSearch and performing different kinds of k-NN search. Percolator | [`percolator`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/percolator/): Specifies to treat this field as a query. Derived | [`derived`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/derived/): Creates new fields dynamically by executing scripts on existing fields. -Star Tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Pre-computes aggregations and stores in a Star Tree Index to accelerate the performance of aggregation queries. +Star-tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Pre-computes aggregations and stores them in a [star-tree index](https://docs.pinot.apache.org/basics/indexing/star-tree-index), accelerating the performance of aggregation queries. ## Arrays From f4d3a7969e5b1f99121e10c118742f7e0363869e Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:24:16 -0500 Subject: [PATCH 14/29] Update improving-search-performance.md Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _search-plugins/improving-search-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_search-plugins/improving-search-performance.md b/_search-plugins/improving-search-performance.md index 3172f0d925..d70e653978 100644 --- a/_search-plugins/improving-search-performance.md +++ b/_search-plugins/improving-search-performance.md @@ -13,4 +13,4 @@ OpenSearch offers several ways to improve search performance: - Search segments concurrently using [concurrent segment search]({{site.url}}{{site.baseurl}}/search-plugins/concurrent-segment-search/). -- Improve performance of aggregations using [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/). \ No newline at end of file +- Improve performance of aggregations using a [star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/). From b4205dd34a2a3d64d25154531fabcb343c657063 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:11:17 -0500 Subject: [PATCH 15/29] Update star-tree-index.md Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _search-plugins/star-tree-index.md | 119 ++++++++++++++++------------- 1 file changed, 65 insertions(+), 54 deletions(-) diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 2b40383e90..f2daf57de4 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -1,70 +1,79 @@ --- layout: default -title: Star Tree index +title: Star-tree index parent: Improving search performance nav_order: 54 --- -# Star tree index +# Star-tree index This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star Tree Index (STIX) is a multi-field index that improves the performance of aggregations. +Star-tree index is a multi-field index that improves the performance of aggregations. -OpenSearch will automatically use the STIX to optimize aggregations if the fields queried are part of STIX dimension fields and the aggregations are on STIX metrics fields. No changes are required in the query syntax or the request parameters. +OpenSearch will automatically use the star-tree index to optimize aggregations if the fields queried are part of star-tree index dimension fields and the aggregations are on star-tree index metrics fields. No changes are required in the query syntax or the request parameters. -## Star tree index structure +## When to use a star-tree index -A Star Tree index containing two dimensions and two metrics +Star-tree index can be used to perform faster aggregations. Consider the following criteria and features when deciding to use a star-tree index: -Star Tree index structure as portrayed in the above figure, consists of mainly two parts: -- Star Tree and -- Sorted and aggregated Star Tree documents backed by doc-values indexes - - The values are sorted based on the order of `ordered_dimension`, in the above example, first by `status` and then by `port` for each of the status. - - For each of the unique dimension value combinations, the aggregated values for all the metrics such as `avg(size)` and `count(requests)` are pre-computed during ingestion time. +- Star-tree indexes natively support multi-field aggregations. +- Star-tree indexes will be created in real-time as part of the indexing process, so the data in a star-tree will always be up to date. +- A star-tree index consolidates data making the index efficient at paging and using less IO for search queries. -Each node in the Star Tree points to a range of Star Tree documents. -A node is further split into child nodes based on [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/star-tree/#star-tree-configuration-parameters). -The number of documents a leaf node points to is less than or equal to `max_leaf_docs`. This ensures the maximum number of documents that gets traversed to get to the aggregated value is at most `max_leaf_docs`, thus providing predictable latency. +## Limitations -There are special nodes called `star nodes (*)` which helps in skipping non-competitive nodes and also in fetching aggregated document wherever applicable during query time. +Star-tree indexes contain the following limitations: -The figure contains three examples explaining the Star Tree traversal during query: -- Compute average request size aggregation with Terms query where port equals 8443 and status equals 200 (Support for Terms query will be added in upcoming release, see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15257)) -- Compute count of requests aggregation with Term query where status equals 200 (query traverses through * node of `port` dimension since `port` is not present as part of query) -- Compute average request size aggregation with Term query where port equals 5600 (query traverses through * node of `status` dimension since `status` is not present as part of query). -
The second and third examples uses star nodes. +- Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for ina star-tree index. +- A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-trees dimensions and the aggregated fields are a subset of a star-trees metrics. +- After the star-tree index is enabled for an index, it cannot be disabled. In order to disable the star-tree idnex, the data in the index must be re-indexed without the star-tree mapping. Furthrmore, changing a star-tree configuration will also require a re-index operation. +- [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported +- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported. Support for more features will be released in upcoming versions. +- The cardinality of the dimensions should not be very high (like `_id` fields). High cardinality leads to higher storage usage and higher query latency. +## Star-tree index structure -## When to use star tree index -Star Tree index can be used to perform faster aggregations with a constant upper bound on query latency. -- Star Tree natively supports multi field aggregations -- Star Tree index will be created in real time as part of indexing, so the data in Star Tree will always be up to date. -- Star Tree index consolidates the data and hence it is storage efficient. It helps in efficient paging and lesser IO utilization for search queries. +The following image illustrates a standard star-tree index structure. -## Considerations -- STIX should only be used on indexes whose data is not updated or deleted, as updates and/or deletes are not accounted in STIX. -- Star Tree index will be used for aggregation queries only if the fields getting queried is a subset of the Star Tree's dimensions and fields getting aggregated is a subset of Start Tree's metrics -- Once Star Tree index is enabled for an index, it cannot be disabled. The data has to be re-indexed without the Star Tree mapping to remove Star Tree from the index. - - Changing Star Tree configuration will also require a re-index operation. -- [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported -- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported currently. Support for more features will be released in upcoming versions. -- The cardinality of the dimensions should not be very high (like `_id` fields), otherwise it leads to high storage usage and higher query latency. +A star-tree  index containing two dimensions and two metrics + +Sorted and aggregated star-tree documents are backed by `doc-values` in an index. Values follow the following patternL + +- The values are sorted based on the order of `ordered_dimension`, in the above example, first by `status` and then by `port` for each of the status. +- For each unique dimension value combination, the aggregated values for all the metrics such as `avg(size)` and `count(requests)` are pre-computed during ingestion time. + +### Leaf nodes + +Each node in the star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the[max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/star-tree/#star-tree-configuration-parameters). The number of documents a leaf node points to is less than or equal to the number `max_leaf_docs` set. This ensures the maximum number of documents that traverse across nodes to get to the aggregated value is at most the `max_leaf_docs`, which provides predictable latency. + +### Star nodes + +`star nodes (*)` fetch aggregated document whenever applicable during query time. + +The star-tree index structure contains three examples explaining how documents traverse star-tree nodes during a `Term` query, based on the compute average request size -## Enabling star tree index -- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled"` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). +Support for the `Term` query will be added in upcoming release. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). +{: .note} + +- Where port the equals `8443` and status equals `200`. Because the status equals `200`, the document does not traverse through a star node. +- Where status equals `200`. The query traverses through a star node in the `port` dimension, since `port` is not present as part of query. +- Where port equals `5600`. The query traverses through star node in the `status` dimension, since `status` is not present as part of query. + +## Enabling the star-tree index + +To use the star-tree index, modify the following settings: + +- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. +- Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your star-tree mapping. -## Examples - -The following examples show how to use Star Tree index. -### Defining star tree index in mappings +## Example -Define Star Tree configuration in index mappings when creating an index.
-To create Star Tree index to pre-compute aggregations for `size` and `latency` fields for all the combinations of values in `port` and `status` fields indexed in the `logs` index, configure the following mapping: +In the following example, index mappings define the star-tree configuration. This star-tree index pre-computes aggregations in the `log` index. The aggregations are calculated using the `size` and `latency` fields for all the combinations of values indexes in `port` and `status` fields. ```json PUT logs @@ -123,20 +132,19 @@ PUT logs } ``` -For detailed information about Star Tree index mapping and parameters see [Star Tree field type]({{site.url}}{{site.baseurl}}/field-types/star-tree/). +For detailed information about star-tree index mapping and parameters see [star-tree field type]({{site.url}}{{site.baseurl}}/field-types/star-tree/). ## Supported query and aggregations -Star Tree index can be used to optimize aggregations. The list of supported queries is given below, support for more queries will be added in upcoming releases (see [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/15257)). +Star-tree indexes can be used to optimize queries and aggregations. ### Supported queries -The following queries are supported as of OpenSearch 2.18 [ when supported aggregations are specified ]
+The following queries are supported as of OpenSearch 2.18: - [Term query](https://opensearch.org/docs/latest/query-dsl/term/term/) - [Match all docs query](https://opensearch.org/docs/latest/query-dsl/match-all/) -Ensure the following in star tree index mapping, -- The fields present in the query must be present as part of `ordered_dimensions` as part of Star Tree configuration. +To use queries, the queries fields must present in the `ordered_dimensions` section of the star-tree configuration. ### Supported aggregations @@ -147,12 +155,15 @@ Following metric aggregations are supported as of OpenSearch 2.18. - [Value count](https://opensearch.org/docs/latest/aggregations/metric/value-count/) - [Average](https://opensearch.org/docs/latest/aggregations/metric/average/) -Ensure the following in Star Tree index mapping, -- The fields present in the aggregation must be present as part of `metrics` as part of Star Tree configuration. -- The metric aggregation type must be part of `stats` parameter. +To use aggregations: + +- The fields must present in the `metrics` section of the star-tree configuration. +- The metric aggregation type must be part of the `stats` parameter. ### Examples -To get sum of `size` for all error logs with `status=500` with the [example mapping](#defining-star-tree-index-in-mappings) : + +The following example gets the sum of the `size`field for all error logs with `status=500`, using the [example mapping](#defining-star-tree-index-in-mappings): + ```json POST /logs/_search { @@ -171,8 +182,8 @@ POST /logs/_search } ``` -This query will get optimized automatically as Star Tree index will be used. -
With Star Tree index, the result will be retrieved from a single aggregated document as it traverses to the `status=500` node as opposed to current query execution which scans through all the matching documents and perform summation. -
This will result in lower query latency. +With the star-tree index, the result will be retrieved from a single aggregated document as it traverses to the `status=500` node, as opposed to scanning through all the matching documents. This will results in lower query latency. + +## Using queries with the star-tree index -You can set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using Star Tree index. \ No newline at end of file +Set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using star-tree index. From 4aea8bfc70112d40e424f6fdf0c0662932597747 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:12:08 -0500 Subject: [PATCH 16/29] Update star-tree.md Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index d5fdf59d20..71039a7693 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -15,16 +15,11 @@ If a star-tree index is configured as part of an index mapping, the star-tree in OpenSearch will automatically use the star-tree index to optimize aggregations if the fields queried are part of star-tree index dimension fields and the aggregations are on star-tree index metrics fields. No changes are required in the query syntax or the request parameters. -For more information, see [Star Tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) +For more information, see [star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) ## Prerequisites -To use the star-tree index, fulfill the following prerequisites: - -- Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). -- Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). -- Set the `index.composite_index` index setting to `true` during index creation. -- Enable `doc_values` : Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your star-tree mapping. +To use the star-tree index, follow the instruction in [Enabling the star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index#enabling-the-star-tree-index). ## Limitations @@ -37,9 +32,9 @@ The star-tree index feature has the following limitations: The following examples show how to use a star-tree index -### Star0tree index mapping +### Star-tree index mapping -Define Star Tree mapping under the `composite` section in `mappings`. +Define star-tree mapping under the `composite` section in `mappings`. The following example creates a corresponding star-tree index for all `request_aggs`. To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: @@ -201,3 +196,4 @@ The following optional parameters can be configured with a star-tree index. Thes ## Supported queries and aggregations For more details on supported queries and aggregations, see [supported query and aggregations for a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-query-and-aggregations). + From 1dd9302f7ace9ebde0fdd8fbebedfc1600fbd3de Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:00:32 -0500 Subject: [PATCH 17/29] Apply suggestions from code review Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- .../supported-field-types/star-tree.md | 2 +- _search-plugins/star-tree-index.md | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 71039a7693..af87cfc3c5 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -190,7 +190,7 @@ The following optional parameters can be configured with a star-tree index. Thes | Parameter | Description | | :--- | :--- | -| `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) | +| `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | | `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip creating the star node. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information on star nodes, see [star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) | ## Supported queries and aggregations diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index f2daf57de4..dd4e70f517 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -26,9 +26,9 @@ Star-tree index can be used to perform faster aggregations. Consider the followi Star-tree indexes contain the following limitations: -- Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for ina star-tree index. +- Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. - A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-trees dimensions and the aggregated fields are a subset of a star-trees metrics. -- After the star-tree index is enabled for an index, it cannot be disabled. In order to disable the star-tree idnex, the data in the index must be re-indexed without the star-tree mapping. Furthrmore, changing a star-tree configuration will also require a re-index operation. +- After the star-tree index is enabled for an index, it cannot be disabled. In order to disable the star-tree index, the data in the index must be re-indexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a re-index operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported - Only [limited queries and aggregations](#supported-query-and-aggregations) are supported. Support for more features will be released in upcoming versions. - The cardinality of the dimensions should not be very high (like `_id` fields). High cardinality leads to higher storage usage and higher query latency. @@ -37,12 +37,12 @@ Star-tree indexes contain the following limitations: The following image illustrates a standard star-tree index structure. -A star-tree  index containing two dimensions and two metrics +A star-tree index containing two dimensions and two metrics Sorted and aggregated star-tree documents are backed by `doc-values` in an index. Values follow the following patternL -- The values are sorted based on the order of `ordered_dimension`, in the above example, first by `status` and then by `port` for each of the status. -- For each unique dimension value combination, the aggregated values for all the metrics such as `avg(size)` and `count(requests)` are pre-computed during ingestion time. +- The values are sorted based on the order of `ordered_dimension`, in the previous example, first by `status` and then by `port` for each of the status. +- For each unique dimension value combination, the aggregated values for all the metrics such as `avg(size)` and `count(requests)` are pre-computed during ingestion time. ### Leaf nodes @@ -68,10 +68,10 @@ To use the star-tree index, modify the following settings: - Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). - Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. -- Ensure that the `doc_values` is enabled for the [dimensions](#ordered-dimensions) and [metrics](#metrics) fields used in your star-tree mapping. +- Ensure that the `doc_values` parameter is enabled for the `dimensions` and `metrics` fields used in your star-tree mapping. -## Example +## Example mapping In the following example, index mappings define the star-tree configuration. This star-tree index pre-computes aggregations in the `log` index. The aggregations are calculated using the `size` and `latency` fields for all the combinations of values indexes in `port` and `status` fields. @@ -132,7 +132,7 @@ PUT logs } ``` -For detailed information about star-tree index mapping and parameters see [star-tree field type]({{site.url}}{{site.baseurl}}/field-types/star-tree/). +For detailed information about star-tree index mapping and parameters see [star-tree field type]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/). ## Supported query and aggregations @@ -160,9 +160,9 @@ To use aggregations: - The fields must present in the `metrics` section of the star-tree configuration. - The metric aggregation type must be part of the `stats` parameter. -### Examples +### Aggregation example -The following example gets the sum of the `size`field for all error logs with `status=500`, using the [example mapping](#defining-star-tree-index-in-mappings): +The following example gets the sum of the `size` field for all error logs with `status=500`, using the [example mapping](#example-mapping): ```json POST /logs/_search From f7ef88fa9ed9fa2bad9ed830296d7ea47202efb3 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:01:10 -0500 Subject: [PATCH 18/29] Apply suggestions from code review Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index af87cfc3c5..9fca166eed 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -30,7 +30,7 @@ The star-tree index feature has the following limitations: ## Examples -The following examples show how to use a star-tree index +The following examples show how to use a star-tree index. ### Star-tree index mapping From 37c6f110b0d9f42cb4b78c795a3fbf822f569a60 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:02:28 -0500 Subject: [PATCH 19/29] Apply suggestions from code review Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 9fca166eed..28bdd42ed5 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -191,7 +191,7 @@ The following optional parameters can be configured with a star-tree index. Thes | Parameter | Description | | :--- | :--- | | `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | -| `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip creating the star node. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information on star nodes, see [star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure) | +| `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip creating the star node. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information about star nodes, see [star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | ## Supported queries and aggregations From 704212a87cdb6ab8dc3d29d35b53c23aa98fabc8 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:12:41 -0500 Subject: [PATCH 20/29] Apply suggestions from code review Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 2 +- _search-plugins/star-tree-index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 28bdd42ed5..416a9740b0 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -190,7 +190,7 @@ The following optional parameters can be configured with a star-tree index. Thes | Parameter | Description | | :--- | :--- | -| `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | +| `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | | `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip creating the star node. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information about star nodes, see [star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | ## Supported queries and aggregations diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index dd4e70f517..899e1d8aad 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -46,7 +46,7 @@ Sorted and aggregated star-tree documents are backed by `doc-values` in an index ### Leaf nodes -Each node in the star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the[max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/star-tree/#star-tree-configuration-parameters). The number of documents a leaf node points to is less than or equal to the number `max_leaf_docs` set. This ensures the maximum number of documents that traverse across nodes to get to the aggregated value is at most the `max_leaf_docs`, which provides predictable latency. +Each node in the star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the[max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/#star-tree-configuration-parameters). The number of documents a leaf node points to is less than or equal to the number `max_leaf_docs` set. This ensures the maximum number of documents that traverse across nodes to get to the aggregated value is at most the `max_leaf_docs`, which provides predictable latency. ### Star nodes From fe891e659a215e962e50b829e6281343cbe8fcd4 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:13:11 -0500 Subject: [PATCH 21/29] Update _field-types/supported-field-types/star-tree.md Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 416a9740b0..9d13d25564 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -129,7 +129,7 @@ When using the `ordered_dimesions` parameter, remember the following best practi - Support for other field_types such as `keyword`, `ip` will be released in future versions. For more information, see [GitHub issue #16232](https://github.com/opensearch-project/OpenSearch/issues/16232). - A minimum of `2` and maximum of `10` dimensions are supported per star-tree index. -`ordered_dimensions` supports the following property +`ordered_dimensions` supports the following property. | Parameter | Required/Optional | Description | | :--- | :--- | :--- | From 521fbb02a2d5158b36fe75b30c08c4568bdaefea Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:08:30 -0500 Subject: [PATCH 22/29] Apply suggestions from code review Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _search-plugins/star-tree-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 899e1d8aad..551952bdae 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -26,7 +26,7 @@ Star-tree index can be used to perform faster aggregations. Consider the followi Star-tree indexes contain the following limitations: -- Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. +- Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. - A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-trees dimensions and the aggregated fields are a subset of a star-trees metrics. - After the star-tree index is enabled for an index, it cannot be disabled. In order to disable the star-tree index, the data in the index must be re-indexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a re-index operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported From 6a5d89e76b35e3e1ae7a6ea41840cc09075281e7 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:27:18 -0500 Subject: [PATCH 23/29] Apply suggestions from code review Co-authored-by: Nathan Bower Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/index.md | 2 +- .../supported-field-types/star-tree.md | 70 +++++++++---------- .../improving-search-performance.md | 2 +- _search-plugins/star-tree-index.md | 60 ++++++++-------- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/_field-types/supported-field-types/index.md b/_field-types/supported-field-types/index.md index f97f2a1384..5540e73f4e 100644 --- a/_field-types/supported-field-types/index.md +++ b/_field-types/supported-field-types/index.md @@ -30,7 +30,7 @@ IP | [`ip`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/ip/): k-NN vector | [`knn_vector`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/knn-vector/): Allows indexing a k-NN vector into OpenSearch and performing different kinds of k-NN search. Percolator | [`percolator`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/percolator/): Specifies to treat this field as a query. Derived | [`derived`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/derived/): Creates new fields dynamically by executing scripts on existing fields. -Star-tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Pre-computes aggregations and stores them in a [star-tree index](https://docs.pinot.apache.org/basics/indexing/star-tree-index), accelerating the performance of aggregation queries. +Star-tree | [`star_tree`]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/): Precomputes aggregations and stores them in a [star-tree index](https://docs.pinot.apache.org/basics/indexing/star-tree-index), accelerating the performance of aggregation queries. ## Arrays diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 9d13d25564..1f5e7d1c48 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -1,32 +1,32 @@ --- layout: default -title: Star Tree +title: Star-tree nav_order: 61 parent: Supported field types --- # Star-tree field type -This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). +This is an experimental feature and is not recommended for use in a production environment. For updates on the progress of the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -[Star-tree index](https://docs.pinot.apache.org/basics/indexing/star-tree-index) pre-computes aggregations, accelerating the performance of aggregation queries. +A [star-tree index](https://docs.pinot.apache.org/basics/indexing/star-tree-index) precomputes aggregations, accelerating the performance of aggregation queries. If a star-tree index is configured as part of an index mapping, the star-tree index is created and maintained as data is ingested in real time. -OpenSearch will automatically use the star-tree index to optimize aggregations if the fields queried are part of star-tree index dimension fields and the aggregations are on star-tree index metrics fields. No changes are required in the query syntax or the request parameters. +OpenSearch will automatically use the star-tree index to optimize aggregations if the queried fields are part of star-tree index dimension fields and the aggregations are on star-tree index metric fields. No changes are required in the query syntax or the request parameters. -For more information, see [star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/) +For more information, see [Star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/). ## Prerequisites -To use the star-tree index, follow the instruction in [Enabling the star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index#enabling-the-star-tree-index). +To use a star-tree index, follow the instructions in [Enabling a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index#enabling-the-star-tree-index). ## Limitations The star-tree index feature has the following limitations: -- A star-tree index should only be used on indexes whose data is not updated or deleted, as standard updates and deletions are not accounted in the star-tree index. -- Currently, only `one` star-tree index can be created per index. Support for multiple star-trees will be added in a future release. +- A star-tree index should only be used on indexes whose data is not updated or deleted because standard updates and deletions are not accounted for in a star-tree index. +- Currently, only `one` star-tree index can be created per index. Support for multiple star-trees will be added in a future version. ## Examples @@ -34,9 +34,9 @@ The following examples show how to use a star-tree index. ### Star-tree index mapping -Define star-tree mapping under the `composite` section in `mappings`. +Define star-tree mapping in the `composite` section in `mappings`. -The following example creates a corresponding star-tree index for all `request_aggs`. To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: +The following example API request creates a corresponding star-tree index for all `request_aggs`. To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: ```json PUT logs @@ -107,47 +107,47 @@ PUT logs -## Star tree mapping parameters +## Star-tree mapping parameters -Specify any star-tree configuration mapping options under the `config` section. All parameters are final and cannot be modified without reindexing documents. +Specify any star-tree configuration mapping options in the `config` section. Parameters cannot be modified without reindexing documents. The star-tree `config` section supports the following property. | Parameter | Required/Optional | Description | | :--- | :--- | :--- | -| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. +| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of the index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. ### Ordered dimensions The `ordered_dimensions` parameter are fields based on which metrics will be aggregated in a star-tree index. The star-tree index will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. -When using the `ordered_dimesions` parameter, remember the following best practices: +When using the `ordered_dimesions` parameter, follow these best practices: -- The order of dimensions matter. You can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. -- Avoid high cardinality fields as dimensions. High cardinality fields adversely affect storage space, indexing throughput, and query performance. -- Currently, supported fields for `ordered_dimensions` are all [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. For more information, see [GitHub issue #15231](https://github.com/opensearch-project/OpenSearch/issues/15231). -- Support for other field_types such as `keyword`, `ip` will be released in future versions. For more information, see [GitHub issue #16232](https://github.com/opensearch-project/OpenSearch/issues/16232). -- A minimum of `2` and maximum of `10` dimensions are supported per star-tree index. +- The order of dimensions matters. You can define the dimensions ordered from the highest cardinality to the lowest cardinality for efficient storage and query pruning. +- Avoid using high-cardinality fields as dimensions. High-cardinality fields adversely affect storage space, indexing throughput, and query performance. +- Currently, fields supported by the `ordered_dimensions` parameter are all [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/), with the exception of `unsigned_long`. For more information, see [GitHub issue #15231](https://github.com/opensearch-project/OpenSearch/issues/15231). +- Support for other field types, such as `keyword` and `ip`, will be added in future versions. For more information, see [GitHub issue #16232](https://github.com/opensearch-project/OpenSearch/issues/16232). +- A minimum of `2` and a maximum of `10` dimensions are supported per star-tree index. -`ordered_dimensions` supports the following property. +The `ordered_dimensions` parameter supports the following property. | Parameter | Required/Optional | Description | | :--- | :--- | :--- | -| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. | +| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of the index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. | ### Metrics -Configure any metric fields for which you need to perform aggregations. `Metrics` are required as part of a star-tree configuration. +Configure any metric fields on which you need to perform aggregations. `Metrics` are required as part of a star-tree configuration. -When using `metrics`, remember the following best practices: +When using `metrics`, follow these best practices: -- Currently, supported fields for `metrics` are all [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/) with the exception of `unsigned_long`. For more information, see [GitHub issue #15231](https://github.com/opensearch-project/OpenSearch/issues/15231). -- Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg` and `Value_count`. - - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed and is derived on query time. Rest of the base metrics are indexed. +- Currently, fields supported by `metrics` are all [numeric field types](https://opensearch.org/docs/latest/field-types/supported-field-types/numeric/), with the exception of `unsigned_long`. For more information, see [GitHub issue #15231](https://github.com/opensearch-project/OpenSearch/issues/15231). +- Supported metric aggregations include `Min`, `Max`, `Sum`, `Avg`, and `Value_count`. + - `Avg` is a derived metric based on `Sum` and `Value_count` and is not indexed when a query is run. The remaining base metrics are indexed. - A maximum of `100` base metrics are supported per star-tree index. -If `Min`, `Max`, `Sum` and `Value_count` are defined as `metrics` for each field then up to 25 such fields can be configured, as shown in the following example: +If `Min`, `Max`, `Sum`, and `Value_count` are defined as `metrics` for each field, then up to 25 such fields can be configured, as shown in the following example: ```json { @@ -177,23 +177,23 @@ If `Min`, `Max`, `Sum` and `Value_count` are defined as `metrics` for each field #### Properties -The `metrics` parameter supports the following properties: +The `metrics` parameter supports the following properties. | Parameter | Required/Optional | Description | | :--- | :--- | :--- | -| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. | -| `stats` | Optional | A list of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Default is `Sum` and `Value_count`.
`Avg` is a derived metric stat which will automatically be supported in queries if `Sum` and `Value_Count` are present as part of metric `stats`. +| `name` | Required | The name of the field. The field name should be present in the `properties` section as part of the index `mapping`. Ensure that the `doc_values` setting is `enabled` for any associated fields. | +| `stats` | Optional | A list of metric aggregations computed for each field. You can choose between `Min`, `Max`, `Sum`, `Avg`, and `Value Count`.
Default is `Sum` and `Value_count`.
`Avg` is a derived metric statistic that will automatically be supported in queries if `Sum` and `Value_Count` are present as part of metric `stats`. -### Star tree configuration parameters +### Star-tree configuration parameters -The following optional parameters can be configured with a star-tree index. These are final and cannot be modified post index creation. +The following parameters are optional and cannot be modified following index creation. | Parameter | Description | | :--- | :--- | -| `max_leaf_docs` | The maximum number of star-tree documents a leaf node can point to. After the maximum number is reached post which the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [star tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | -| `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip creating the star node. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information about star nodes, see [star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | +| `max_leaf_docs` | The maximum number of star-tree documents that a leaf node can point to. After the maximum number of documents is reached, the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [Star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | +| `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip star node creation. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information about star nodes, see [Star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | ## Supported queries and aggregations -For more details on supported queries and aggregations, see [supported query and aggregations for a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-query-and-aggregations). +For more information about supported queries and aggregations, see [Supported queries and aggregations for a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#supported-queries-and-aggregations). diff --git a/_search-plugins/improving-search-performance.md b/_search-plugins/improving-search-performance.md index d70e653978..4cc0a60dc0 100644 --- a/_search-plugins/improving-search-performance.md +++ b/_search-plugins/improving-search-performance.md @@ -13,4 +13,4 @@ OpenSearch offers several ways to improve search performance: - Search segments concurrently using [concurrent segment search]({{site.url}}{{site.baseurl}}/search-plugins/concurrent-segment-search/). -- Improve performance of aggregations using a [star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/). +- Improve aggregation performance using a [star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/). diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 551952bdae..01e09e2dc4 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -7,31 +7,31 @@ nav_order: 54 # Star-tree index -This is an experimental feature and is not recommended for use in a production environment. For updates on the progress the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). +This is an experimental feature and is not recommended for use in a production environment. For updates on the progress of the feature or if you want to leave feedback, join the discussion on the [OpenSearch forum](https://forum.opensearch.org/). {: .warning} -Star-tree index is a multi-field index that improves the performance of aggregations. +A star-tree index is a multi-field index that improves the performance of aggregations. -OpenSearch will automatically use the star-tree index to optimize aggregations if the fields queried are part of star-tree index dimension fields and the aggregations are on star-tree index metrics fields. No changes are required in the query syntax or the request parameters. +OpenSearch will automatically use a star-tree index to optimize aggregations if the queried fields are part of star-tree index dimension fields and the aggregations are on star-tree index metric fields. No changes are required in the query syntax or the request parameters. ## When to use a star-tree index -Star-tree index can be used to perform faster aggregations. Consider the following criteria and features when deciding to use a star-tree index: +A star-tree index can be used to perform faster aggregations. Consider the following criteria and features when deciding to use a star-tree index: - Star-tree indexes natively support multi-field aggregations. -- Star-tree indexes will be created in real-time as part of the indexing process, so the data in a star-tree will always be up to date. -- A star-tree index consolidates data making the index efficient at paging and using less IO for search queries. +- Star-tree indexes are created in real time as part of the indexing process, so the data in a star-tree will always be up to date. +- A star-tree index consolidates data, increasing index paging efficiency and using less IO for search queries. ## Limitations -Star-tree indexes contain the following limitations: +Star-tree indexes have the following limitations: - Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. -- A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-trees dimensions and the aggregated fields are a subset of a star-trees metrics. -- After the star-tree index is enabled for an index, it cannot be disabled. In order to disable the star-tree index, the data in the index must be re-indexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a re-index operation. -- [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported -- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported. Support for more features will be released in upcoming versions. -- The cardinality of the dimensions should not be very high (like `_id` fields). High cardinality leads to higher storage usage and higher query latency. +- A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-tree's dimensions and the aggregated fields are a subset of a star-tree's metrics. +- After a star-tree index is enabled, it cannot be disabled. In order to disable a star-tree index, the data in the index must be reindexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a reindex operation. +- [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported. +- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported. Support for more features will be added in future versions. +- The cardinality of the dimensions should not be very high (as with `_id` fields). Higher cardinality leads to increased storage usage and query latency. ## Star-tree index structure @@ -39,41 +39,41 @@ The following image illustrates a standard star-tree index structure. A star-tree index containing two dimensions and two metrics -Sorted and aggregated star-tree documents are backed by `doc-values` in an index. Values follow the following patternL +Sorted and aggregated star-tree documents are backed by `doc-values` in an index. `doc_values` use the following pattern: - The values are sorted based on the order of `ordered_dimension`, in the previous example, first by `status` and then by `port` for each of the status. -- For each unique dimension value combination, the aggregated values for all the metrics such as `avg(size)` and `count(requests)` are pre-computed during ingestion time. +- For each unique dimension/value combination, the aggregated values for all the metrics, such as `avg(size)` and `count(requests)`, are precomputed during ingestion. ### Leaf nodes -Each node in the star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the[max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/#star-tree-configuration-parameters). The number of documents a leaf node points to is less than or equal to the number `max_leaf_docs` set. This ensures the maximum number of documents that traverse across nodes to get to the aggregated value is at most the `max_leaf_docs`, which provides predictable latency. +Each node in a star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/#star-tree-configuration-parameters). The number of documents that a leaf node points to is less than or equal to the number set by `max_leaf_docs`. This ensures that the maximum number of documents that traverse nodes to get to the aggregated value is at most `max_leaf_docs`, which provides predictable latency. ### Star nodes `star nodes (*)` fetch aggregated document whenever applicable during query time. -The star-tree index structure contains three examples explaining how documents traverse star-tree nodes during a `Term` query, based on the compute average request size +The star-tree index structure contains three examples demonstrating how a document traverses or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions. -Support for the `Term` query will be added in upcoming release. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). +Support for the `Term` query will be added in a future version. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). {: .note} -- Where port the equals `8443` and status equals `200`. Because the status equals `200`, the document does not traverse through a star node. +- Where port the equals `8443` and status equals `200`. Because the status equals `200`, the query does not traverse through a star node and the aggregated metric is stored at the end of a star-tree document. - Where status equals `200`. The query traverses through a star node in the `port` dimension, since `port` is not present as part of query. -- Where port equals `5600`. The query traverses through star node in the `status` dimension, since `status` is not present as part of query. +- Where port equals `5600`. The query traverses through a star node in the `status` dimension, since `status` is not present as part of query. -## Enabling the star-tree index +## Enabling a star-tree index -To use the star-tree index, modify the following settings: +To use a star-tree index, modify the following settings: - Set the feature flag `opensearch.experimental.feature.composite_index.star_tree.enabled` to `true`. For more information about enabling and disabling feature flags, see [Enabling experimental features]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/experimental/). -- Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). +- Set the `indices.composite_index.star_tree.enabled` setting to `true`. For instructions on how to configure OpenSearch, see [Configuring settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/index/#static-settings). - Set the `index.composite_index` index setting to `true` during index creation. - Ensure that the `doc_values` parameter is enabled for the `dimensions` and `metrics` fields used in your star-tree mapping. ## Example mapping -In the following example, index mappings define the star-tree configuration. This star-tree index pre-computes aggregations in the `log` index. The aggregations are calculated using the `size` and `latency` fields for all the combinations of values indexes in `port` and `status` fields. +In the following example, index mappings define the star-tree configuration. This star-tree index precomputes aggregations in the `log` index. The aggregations are calculated using the `size` and `latency` fields for all the combinations of values indexed in the `port` and `status` fields: ```json PUT logs @@ -134,7 +134,7 @@ PUT logs For detailed information about star-tree index mapping and parameters see [star-tree field type]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/). -## Supported query and aggregations +## Supported queries and aggregations Star-tree indexes can be used to optimize queries and aggregations. @@ -144,11 +144,11 @@ The following queries are supported as of OpenSearch 2.18: - [Term query](https://opensearch.org/docs/latest/query-dsl/term/term/) - [Match all docs query](https://opensearch.org/docs/latest/query-dsl/match-all/) -To use queries, the queries fields must present in the `ordered_dimensions` section of the star-tree configuration. +To use queries with a star-tree index, the query's fields must be present in the `ordered_dimensions` section of the star-tree configuration. ### Supported aggregations -Following metric aggregations are supported as of OpenSearch 2.18. +The following metric aggregations are supported as of OpenSearch 2.18: - [Sum](https://opensearch.org/docs/latest/aggregations/metric/sum/) - [Minimum](https://opensearch.org/docs/latest/aggregations/metric/minimum/) - [Maximum](https://opensearch.org/docs/latest/aggregations/metric/maximum/) @@ -157,7 +157,7 @@ Following metric aggregations are supported as of OpenSearch 2.18. To use aggregations: -- The fields must present in the `metrics` section of the star-tree configuration. +- The fields must be present in the `metrics` section of the star-tree configuration. - The metric aggregation type must be part of the `stats` parameter. ### Aggregation example @@ -182,8 +182,8 @@ POST /logs/_search } ``` -With the star-tree index, the result will be retrieved from a single aggregated document as it traverses to the `status=500` node, as opposed to scanning through all the matching documents. This will results in lower query latency. +With the star-tree index, the result will be retrieved from a single aggregated document as it traverses to the `status=500` node, as opposed to scanning through all of the matching documents. This results in lower query latency. -## Using queries with the star-tree index +## Using queries with a star-tree index -Set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using star-tree index. +Set the `indices.composite_index.star_tree.enabled` setting to `false` to run queries without using a star-tree index. From d2499469f82d365907cf9ecd5d84def8e07d1558 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:35:11 -0500 Subject: [PATCH 24/29] Apply suggestions from code review Co-authored-by: Nathan Bower Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 4 ++-- _search-plugins/star-tree-index.md | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 1f5e7d1c48..50b77a9114 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -25,7 +25,7 @@ To use a star-tree index, follow the instructions in [Enabling a star-tree index The star-tree index feature has the following limitations: -- A star-tree index should only be used on indexes whose data is not updated or deleted because standard updates and deletions are not accounted for in a star-tree index. +- A star-tree index should only be enabled on indexes whose data is not updated or deleted because standard updates and deletions are not accounted for in a star-tree index. - Currently, only `one` star-tree index can be created per index. Support for multiple star-trees will be added in a future version. ## Examples @@ -190,7 +190,7 @@ The following parameters are optional and cannot be modified following index cre | Parameter | Description | | :--- | :--- | -| `max_leaf_docs` | The maximum number of star-tree documents that a leaf node can point to. After the maximum number of documents is reached, the nodes will be split to the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [Star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | +| `max_leaf_docs` | The maximum number of star-tree documents that a leaf node can point to. After the maximum number of documents is reached, the nodes will be split based on the value of the next dimension. Default is `10000`. A lower value will use more storage but result in faster query performance. Inversely, a higher value will use less storage but result in slower query performance. For more information, see [Star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | | `skip_star_node_creation_for_dimensions` | A list of dimensions for which a star-tree index will skip star node creation. When `true`, this reduces storage size at the expense of query performance. Default is `false`. For more information about star nodes, see [Star-tree indexing structure]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index/#star-tree-index-structure). | ## Supported queries and aggregations diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 01e09e2dc4..99b88f41ef 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -26,7 +26,7 @@ A star-tree index can be used to perform faster aggregations. Consider the follo Star-tree indexes have the following limitations: -- Star-tree index should only be used on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. +- A star-tree index should only be enabled on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. - A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-tree's dimensions and the aggregated fields are a subset of a star-tree's metrics. - After a star-tree index is enabled, it cannot be disabled. In order to disable a star-tree index, the data in the index must be reindexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a reindex operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported. @@ -41,16 +41,16 @@ The following image illustrates a standard star-tree index structure. Sorted and aggregated star-tree documents are backed by `doc-values` in an index. `doc_values` use the following pattern: -- The values are sorted based on the order of `ordered_dimension`, in the previous example, first by `status` and then by `port` for each of the status. +- The values are sorted based on the order of their `ordered_dimension`. The preceding image, the dimensions are determined by the `status` setting and then by the `port` for each status. - For each unique dimension/value combination, the aggregated values for all the metrics, such as `avg(size)` and `count(requests)`, are precomputed during ingestion. ### Leaf nodes -Each node in a star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/#star-tree-configuration-parameters). The number of documents that a leaf node points to is less than or equal to the number set by `max_leaf_docs`. This ensures that the maximum number of documents that traverse nodes to get to the aggregated value is at most `max_leaf_docs`, which provides predictable latency. +Each node in a star-tree index points to a range of star-tree documents. Nodes can be further split into child nodes based on the [max_leaf_docs configuration]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/#star-tree-configuration-parameters). The number of documents that a leaf node points to is less than or equal to the number set by `max_leaf_docs`. This ensures that the maximum number of documents that need to traverse nodes to derive an aggregated value is at most the number of `max_leaf_docs`, which provides predictable latency. ### Star nodes -`star nodes (*)` fetch aggregated document whenever applicable during query time. +Star nodes are children of non-leaf nodes which contain pre-aggregated records for data split after dimension removal, aggregating metrics for rows containing dimensions with identical values. These aggregated documents are then appended to end of star-tree documents. If a document does contain a dimension with identical values, it traverses through the star node. The star-tree index structure contains three examples demonstrating how a document traverses or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions. @@ -132,7 +132,7 @@ PUT logs } ``` -For detailed information about star-tree index mapping and parameters see [star-tree field type]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/). +For detailed information about star-tree index mappings and parameters see [Star-tree field type]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/). ## Supported queries and aggregations From 6ce9d2213ffaff728d0dd18553668f4bb0e1499a Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:42:27 -0500 Subject: [PATCH 25/29] Apply suggestions from code review Co-authored-by: Nathan Bower Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 4 ++-- _search-plugins/star-tree-index.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index 50b77a9114..ea6fcc60e7 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -19,7 +19,7 @@ For more information, see [Star-tree index]({{site.url}}{{site.baseurl}}/search- ## Prerequisites -To use a star-tree index, follow the instructions in [Enabling a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index#enabling-the-star-tree-index). +To use a star-tree index, follow the instructions in [Enabling a star-tree index]({{site.url}}{{site.baseurl}}/search-plugins/star-tree-index#enabling-a-star-tree-index). ## Limitations @@ -119,7 +119,7 @@ The star-tree `config` section supports the following property. ### Ordered dimensions -The `ordered_dimensions` parameter are fields based on which metrics will be aggregated in a star-tree index. The star-tree index will be picked for querying only if all the fields in the query are part of the `ordered_dimensions`. +The `ordered_dimensions` parameter contains fields based on which metrics will be aggregated in a star-tree index. The star-tree index will be selected for querying only if all the fields in the query are part of the `ordered_dimensions`. When using the `ordered_dimesions` parameter, follow these best practices: diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 99b88f41ef..3dfe81c2d1 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -30,7 +30,7 @@ Star-tree indexes have the following limitations: - A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-tree's dimensions and the aggregated fields are a subset of a star-tree's metrics. - After a star-tree index is enabled, it cannot be disabled. In order to disable a star-tree index, the data in the index must be reindexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a reindex operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported. -- Only [limited queries and aggregations](#supported-query-and-aggregations) are supported. Support for more features will be added in future versions. +- Only [limited queries and aggregations](#supported-queries-and-aggregations) are supported. Support for more features will be added in future versions. - The cardinality of the dimensions should not be very high (as with `_id` fields). Higher cardinality leads to increased storage usage and query latency. ## Star-tree index structure From c0c5ec020b4f6600cc1d2f77322ce3755108a63a Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:25:07 -0500 Subject: [PATCH 26/29] Apply suggestions from code review Co-authored-by: Nathan Bower Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 2 +- _search-plugins/star-tree-index.md | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index ea6fcc60e7..f9b89c936e 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -34,7 +34,7 @@ The following examples show how to use a star-tree index. ### Star-tree index mapping -Define star-tree mapping in the `composite` section in `mappings`. +Define star-tree index mapping in the `composite` section in `mappings`. The following example API request creates a corresponding star-tree index for all `request_aggs`. To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 3dfe81c2d1..c43109fada 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -26,8 +26,8 @@ A star-tree index can be used to perform faster aggregations. Consider the follo Star-tree indexes have the following limitations: -- A star-tree index should only be enabled on indexes whose data is not updated or deleted, as updates and deletions are not accounted for in a star-tree index. -- A star-tree index can be used for aggregation queries only if the fields queried is a subset of the star-tree's dimensions and the aggregated fields are a subset of a star-tree's metrics. +- A star-tree index should only be enabled on indexes whose data is not updated or deleted because updates and deletions are not accounted for in a star-tree index. +- A star-tree index can be used for aggregation queries only if the queried fields are a subset of the star-tree's dimensions and the aggregated fields are a subset of the star-tree's metrics. - After a star-tree index is enabled, it cannot be disabled. In order to disable a star-tree index, the data in the index must be reindexed without the star-tree mapping. Furthermore, changing a star-tree configuration will also require a reindex operation. - [Multi-values/array values]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/index/#arrays) are not supported. - Only [limited queries and aggregations](#supported-queries-and-aggregations) are supported. Support for more features will be added in future versions. @@ -41,7 +41,7 @@ The following image illustrates a standard star-tree index structure. Sorted and aggregated star-tree documents are backed by `doc-values` in an index. `doc_values` use the following pattern: -- The values are sorted based on the order of their `ordered_dimension`. The preceding image, the dimensions are determined by the `status` setting and then by the `port` for each status. +- The values are sorted based on the order of their `ordered_dimension`. In the preceding image, the dimensions are determined by the `status` setting and then by the `port` for each status. - For each unique dimension/value combination, the aggregated values for all the metrics, such as `avg(size)` and `count(requests)`, are precomputed during ingestion. ### Leaf nodes @@ -50,16 +50,16 @@ Each node in a star-tree index points to a range of star-tree documents. Nodes c ### Star nodes -Star nodes are children of non-leaf nodes which contain pre-aggregated records for data split after dimension removal, aggregating metrics for rows containing dimensions with identical values. These aggregated documents are then appended to end of star-tree documents. If a document does contain a dimension with identical values, it traverses through the star node. +Star nodes are children of non-leaf nodes that contain preaggregated records for data split after dimension removal, aggregating metrics for rows containing dimensions with identical values. These aggregated documents are then appended to the end of star-tree documents. If a document does contain a dimension with identical values, it traverses through the star node. The star-tree index structure contains three examples demonstrating how a document traverses or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions. Support for the `Term` query will be added in a future version. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). {: .note} -- Where port the equals `8443` and status equals `200`. Because the status equals `200`, the query does not traverse through a star node and the aggregated metric is stored at the end of a star-tree document. -- Where status equals `200`. The query traverses through a star node in the `port` dimension, since `port` is not present as part of query. -- Where port equals `5600`. The query traverses through a star node in the `status` dimension, since `status` is not present as part of query. +- When the port equals `8443` and the status equals `200`. Because the status equals `200`, the query does not traverse through a star node, and the aggregated metric is stored at the end of a star-tree document. +- When the status equals `200`. The query traverses through a star node in the `port` dimension because `port` is not present as part of the query. +- When the port equals `5600`. The query traverses through a star node in the `status` dimension because `status` is not present as part of the query. ## Enabling a star-tree index @@ -132,7 +132,7 @@ PUT logs } ``` -For detailed information about star-tree index mappings and parameters see [Star-tree field type]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/). +For detailed information about star-tree index mappings and parameters, see [Star-tree field type]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/star-tree/). ## Supported queries and aggregations From e8bdea578bea7b9890e05c207df84b737f1c5aff Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:25:32 -0500 Subject: [PATCH 27/29] Apply suggestions from code review Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _search-plugins/star-tree-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index c43109fada..082563258b 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -39,7 +39,7 @@ The following image illustrates a standard star-tree index structure. A star-tree index containing two dimensions and two metrics -Sorted and aggregated star-tree documents are backed by `doc-values` in an index. `doc_values` use the following pattern: +Sorted and aggregated star-tree documents are backed by `doc_values` in an index. `doc_values` use the following pattern: - The values are sorted based on the order of their `ordered_dimension`. In the preceding image, the dimensions are determined by the `status` setting and then by the `port` for each status. - For each unique dimension/value combination, the aggregated values for all the metrics, such as `avg(size)` and `count(requests)`, are precomputed during ingestion. From 3e372f744bf3d5921bc92e852c9f605295bc68a1 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:44:38 -0500 Subject: [PATCH 28/29] Apply suggestions from code review Co-authored-by: Nathan Bower Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _field-types/supported-field-types/star-tree.md | 4 ++-- _search-plugins/star-tree-index.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_field-types/supported-field-types/star-tree.md b/_field-types/supported-field-types/star-tree.md index f9b89c936e..c33569663c 100644 --- a/_field-types/supported-field-types/star-tree.md +++ b/_field-types/supported-field-types/star-tree.md @@ -32,9 +32,9 @@ The star-tree index feature has the following limitations: The following examples show how to use a star-tree index. -### Star-tree index mapping +### Star-tree index mappings -Define star-tree index mapping in the `composite` section in `mappings`. +Define star-tree index mappings in the `composite` section in `mappings`. The following example API request creates a corresponding star-tree index for all `request_aggs`. To compute metric aggregations for `request_size` and `latency` fields with queries on `port` and `status` fields, configure the following mappings: diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 082563258b..7ecd689f38 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -52,7 +52,7 @@ Each node in a star-tree index points to a range of star-tree documents. Nodes c Star nodes are children of non-leaf nodes that contain preaggregated records for data split after dimension removal, aggregating metrics for rows containing dimensions with identical values. These aggregated documents are then appended to the end of star-tree documents. If a document does contain a dimension with identical values, it traverses through the star node. -The star-tree index structure contains three examples demonstrating how a document traverses or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions. +The star-tree index structure diagram contains the following three examples demonstrating how a document does or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions. Support for the `Term` query will be added in a future version. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). {: .note} From 19eaad0fa223010c5a3e2f7a0fba161ea3238761 Mon Sep 17 00:00:00 2001 From: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:46:02 -0500 Subject: [PATCH 29/29] Update star-tree-index.md Signed-off-by: Naarcha-AWS <97990722+Naarcha-AWS@users.noreply.github.com> --- _search-plugins/star-tree-index.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/_search-plugins/star-tree-index.md b/_search-plugins/star-tree-index.md index 7ecd689f38..8ccbc3a067 100644 --- a/_search-plugins/star-tree-index.md +++ b/_search-plugins/star-tree-index.md @@ -52,14 +52,14 @@ Each node in a star-tree index points to a range of star-tree documents. Nodes c Star nodes are children of non-leaf nodes that contain preaggregated records for data split after dimension removal, aggregating metrics for rows containing dimensions with identical values. These aggregated documents are then appended to the end of star-tree documents. If a document does contain a dimension with identical values, it traverses through the star node. -The star-tree index structure diagram contains the following three examples demonstrating how a document does or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions. - -Support for the `Term` query will be added in a future version. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). -{: .note} +The star-tree index structure diagram contains the following three examples demonstrating how a document does or does not traverse star-tree nodes (indicated by the `*` symbol in the diagram) during a `Term` query, based on the average request size of the query and whether the document contains matching dimensions: - When the port equals `8443` and the status equals `200`. Because the status equals `200`, the query does not traverse through a star node, and the aggregated metric is stored at the end of a star-tree document. - When the status equals `200`. The query traverses through a star node in the `port` dimension because `port` is not present as part of the query. -- When the port equals `5600`. The query traverses through a star node in the `status` dimension because `status` is not present as part of the query. +- When the port equals `5600`. The query traverses through a star node in the `status` dimension because `status` is not present as part of the query. + +Support for the `Term` query will be added in a future version. For more information, see [GitHub issue #15257](https://github.com/opensearch-project/OpenSearch/issues/15257). +{: .note} ## Enabling a star-tree index @@ -139,6 +139,7 @@ For detailed information about star-tree index mappings and parameters, see [Sta Star-tree indexes can be used to optimize queries and aggregations. ### Supported queries + The following queries are supported as of OpenSearch 2.18: - [Term query](https://opensearch.org/docs/latest/query-dsl/term/term/)