[Cases] - Update Incremental ID Mapping#234054
Conversation
ce750a5 to
3b84a74
Compare
|
Pinging @elastic/kibana-cases (Team:Cases) |
|
Cloud deployment initiated, see credentials at: https://buildkite.com/elastic/kibana-deploy-cloud-from-pr/builds/374 |
|
Project deployed, see credentials at: https://buildkite.com/elastic/kibana-deploy-project-from-pr/builds/571 |
There was a problem hiding this comment.
Pull Request Overview
This PR adds a multi-field mapping to the incremental_id field for Cases saved objects, allowing it to be used in both numeric operations and string-based searches. The change addresses data type mismatch errors when combining numeric incremental_id searches with keyword fields.
Key Changes
- Updates the
incremental_idfield mapping to include akeywordsub-field for string operations - Creates model version 4 to handle the mapping migration
- Updates schema validation to accept both numeric and object forms of the field
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
x-pack/platform/plugins/shared/cases/server/saved_object_types/cases/cases.ts |
Adds keyword sub-field mapping and references model version 4 |
x-pack/platform/plugins/shared/cases/server/saved_object_types/cases/model_versions/model_version_4.ts |
Defines migration for adding the multi-field mapping |
x-pack/platform/plugins/shared/cases/server/saved_object_types/cases/schemas/v5.ts |
Creates schema validation for the new field structure |
x-pack/platform/plugins/shared/cases/server/saved_object_types/cases/versioning.test.ts |
Adds test coverage for the model version migration |
src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts |
Updates CI checks with new mapping hashes and version metadata |
packages/kbn-check-saved-objects-cli/current_mappings.json |
Updates the canonical mapping definition |
| }, | ||
| ], | ||
| schemas: { | ||
| forwardCompatibility: casesSchemaV5.extends({}, { unknowns: 'ignore' }), |
There was a problem hiding this comment.
Just for curiosity, should this be casesSchemaV4? or is casesSchemaV4 only used to create casesSchemaV5? 🤔
There was a problem hiding this comment.
@jesuswr This is why there was no v4: #219070 (comment)
We do plan on searching on this field though
There was a problem hiding this comment.
It took me a while to wrap my head around a mismatch in version between the modelVersion and schema.
Usually, schemas and model versions have the same numeric version numbers, so modelVersion2 would have schema2.
In this case, it actually looks to be safe.
There was a problem hiding this comment.
Yea, that's what I thought to but the linked thread above from @adcoelho was helpful in explaining. Though I think it will get confusing in the future. I'll add a comment about it on a follow up pr, thanks @TinaHeiligers !
There was a problem hiding this comment.
I couldn't find specific mentions of casesSchemaV4, but it was being exported in x-pack/platform/plugins/shared/cases/server/saved_object_types/cases/schemas/latest.ts. Won't that affect something?
There was a problem hiding this comment.
No that alone will not affect anything...
However, there is feature code using the fields time_to_acknowledge etc. This means that the forward compatibility schema of model_version_3 will strip these fields if ever invoked (like when we rollback) so features relying on these fields will never see them if we rollback from v3+ -> v3... Something we should also address on this PR by fixing v3's forward compatibility schema, lemme get back to you on the options!
There was a problem hiding this comment.
This is why there was no v4: #219070 (comment)
This comment was about removing the mappings, not the model version. I should probably have stated that a bit more clearly!
There was a problem hiding this comment.
Bc these schemas are only used in fwc I think we should still make the changes on the PR I recommended here #234054 (comment) concretely: create model version 4 with your mappings and schema v4 in this PR (not v5).
We cannot fix the existing latent bug we can only roll forward.
There was a problem hiding this comment.
@jloleysens woudl you suggest that I add all of those fields in the model_version_4.ts as well?
| }, | ||
| ], | ||
| schemas: { | ||
| forwardCompatibility: casesSchemaV5.extends({}, { unknowns: 'ignore' }), |
There was a problem hiding this comment.
It took me a while to wrap my head around a mismatch in version between the modelVersion and schema.
Usually, schemas and model versions have the same numeric version numbers, so modelVersion2 would have schema2.
In this case, it actually looks to be safe.
b293857 to
3b84a74
Compare
5c1eacc to
a024211
Compare
a4d9069 to
e901762
Compare
668398b to
df7b49e
Compare
| }, | ||
| ], | ||
| schemas: { | ||
| forwardCompatibility: casesSchemaV5.extends({}, { unknowns: 'ignore' }), |
There was a problem hiding this comment.
[updated] there's a huge risk with rollbacks right now in that feature code relies on fields that haven't been implemented.
We can't get around that risk and should point it out in the PR description.
Once the changes in #234054 (comment) are made, the modelVersion and schemaVersions should be in sync again for the next modelVersion change.
TinaHeiligers
left a comment
There was a problem hiding this comment.
Changes to casesSchemaV4 LGTM. However, we can't get a round the latent bug where feature code using the fields time_to_acknowledge etc won't see the fields if we were to roll back from v4 to v3.
6baefe0 to
3b2e144
Compare
|
Serverless upgrade testing utilizing |
… src/core/server/integration_tests/ci_checks'
3b2e144 to
dbf6f6e
Compare
💚 Build Succeeded
Metrics [docs]
History
|
## Summary This PR updates the mapping for the `incremental_id` field to be a [mulit-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field). In the initial implementation with just `unsigned_long`, running search when combining this field with non-numeric fields such as `keyword` didn't function due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use). The main concern for this change is initializing a mapping change in the serverless environment, but this was tested against [this PR](elastic#230278) that also enables the functionality that will populate this field. For testing: see elastic#230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
### TLDR We need to utilize `text` in place of `keyword` to not break phrase prefix queries, so introducing the field `incremental_id.text` ### Background A new issue appeared where the current search field `title` and `description` are of mapping type text. This typically shouldn't be a problem, but unfortunately when attempting to run a prefixed query with the new `incremental_id.keyword` field in [this pr](#230278) we received the following error: To test, run [this test](https://github.com/elastic/kibana/blob/8ffa408f560b59cde8f045ff440090a05bf7bdbf/x-pack/platform/test/functional_with_es_ssl/apps/cases/group2/list_view.ts#L397) on [this PR](#230278) (after changing all instances in the UI from `incremental_id.text` back to `incremental_id.keyword`: ``` search_phase_execution_exception Root causes: query_shard_exception: failed to create query: Can only use phrase prefix queries on text fields - not on [cases.incremental_id.keyword] which is of type [keyword] ``` After some digging as to exactly why this was happening, the only documentation regarding this we could find was in this comment: #129424 (comment) . We should most likely add this information to the documentation here as well: https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-prefix-query ? For historical reference of mapping changes to the `incremental_id` see: #234054 The primary concern for this change is initializing a mapping change in the serverless environment, but this has been tested in this pr and tested against [this PR](#230278) that also enables the functionality that will populate this field. CI has also been run to make sure all tests pass with the new mapping to avoid any additional surprises [here](#230278 (comment)) For testing: see #230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary This PR updates the mapping for the `incremental_id` field to be a [mulit-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field). In the initial implementation with just `unsigned_long`, running search when combining this field with non-numeric fields such as `keyword` didn't function due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use). The main concern for this change is initializing a mapping change in the serverless environment, but this was tested against [this PR](elastic#230278) that also enables the functionality that will populate this field. For testing: see elastic#230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
### TLDR We need to utilize `text` in place of `keyword` to not break phrase prefix queries, so introducing the field `incremental_id.text` ### Background A new issue appeared where the current search field `title` and `description` are of mapping type text. This typically shouldn't be a problem, but unfortunately when attempting to run a prefixed query with the new `incremental_id.keyword` field in [this pr](elastic#230278) we received the following error: To test, run [this test](https://github.com/elastic/kibana/blob/8ffa408f560b59cde8f045ff440090a05bf7bdbf/x-pack/platform/test/functional_with_es_ssl/apps/cases/group2/list_view.ts#L397) on [this PR](elastic#230278) (after changing all instances in the UI from `incremental_id.text` back to `incremental_id.keyword`: ``` search_phase_execution_exception Root causes: query_shard_exception: failed to create query: Can only use phrase prefix queries on text fields - not on [cases.incremental_id.keyword] which is of type [keyword] ``` After some digging as to exactly why this was happening, the only documentation regarding this we could find was in this comment: elastic#129424 (comment) . We should most likely add this information to the documentation here as well: https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-prefix-query ? For historical reference of mapping changes to the `incremental_id` see: elastic#234054 The primary concern for this change is initializing a mapping change in the serverless environment, but this has been tested in this pr and tested against [this PR](elastic#230278) that also enables the functionality that will populate this field. CI has also been run to make sure all tests pass with the new mapping to avoid any additional surprises [here](elastic#230278 (comment)) For testing: see elastic#230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary This is a reversion of the revert of this original #228002 of incremental id work. This original revert was done, due to the search functionality in cases being broken when searching on the new `incremental_id` field. It being of type `unsigned_long` meant that ES would not return when it was included alongside text values due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use).. Rather than creating a new field, and making the existing `incremental_id` field dead weight, we instead [update it to a multi-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field), so we can search on this value as text alongside other cases values. The update of the mapping was done here: #234054 #### Functional Changes From Reversion 1. Use of `incremental_id.text` in search functionality in place of `incremental_id` 2. There is no longer an advanced setting to hide the feature in the UI as we feel comfortable releasing it as is, and the field is currently only metadata and doesn't introduce any functional changes outside of searching. ## Testing: Feature Flag: `xpack.cases.incrementalId.enabled: true`. Currently disabled and will be enabled after additional testing during FF When running a clean branch, the feature will work correctly. We've verified locally that the mapping update works successfully via the methods described below, but feel free to test as well to confirm our results 👍🏾 ### Serverless 1. Create a security serverless environment via `qaf`. 4. Create cases in the serverless environment 5. Update images to the build image from this pr via the `--kb-docker-images` flag. 6. Wait for the task to run, and verify the numeric ids are applied to the cases 7. Search for cases by then numeric id via `#{incremental_id value}` and also search for `description + {incremental_id value}` and make sure the query successfully returns ### On-Prem 1. Run main locally 2. Create cases in the local environment 3. Switch branches from main to this branch 4. Wait for the task to run, and verify the numeric ids are applied to the cases 5. Search for cases by then numeric id via `#{id number}` and also search for `description + id number` and make sure the query successfully returns ## OUTDATED The below details were provided for manually updating the mapping via dev tools for testing/validation purposes This PR updates the mapping directly. Here are steps to update the mapping manually in a local instance: 0. Remove changes in `packages/kbn-check-mappings-update-cli/current_mappings.json` 1. Create some tests (there could be error toasts because `incremental_id.text` is not yet created 8. Create an `admin` user and assign `system_indices_superuser` and `superuser` role 9. Go to Dev tools, get the current mapping `GET /.kibana_alerting_cases_9.2.0_001/_mapping` 10. Add `text` as multi-field for `incremental_id` 11. Run `POST /.kibana_alerting_cases_9.2.0_001/_update_by_query` to update existing document 12. Go to Cases and observe the case id can be searched individually or in combination of other texts <details> <summary>mapping update query</summary> ``` PUT /.kibana_alerting_cases_9.2.0_001/_mapping { "properties": { "action": { "dynamic": "false", "properties": { "actionTypeId": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } }, "action_task_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" } } }, "ad_hoc_run_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" }, "end": { "type": "date" }, "rule": { "properties": { "alertTypeId": { "type": "keyword" }, "consumer": { "type": "keyword" } } }, "start": { "type": "date" } } }, "alert": { "dynamic": "false", "properties": { "actions": { "type": "nested", "dynamic": "false", "properties": { "actionRef": { "type": "keyword" }, "actionTypeId": { "type": "keyword" }, "group": { "type": "keyword" } } }, "alertTypeId": { "type": "keyword" }, "artifacts": { "properties": { "investigation_guide": { "properties": { "blob": { "type": "text" } } } } }, "consumer": { "type": "keyword" }, "createdAt": { "type": "date" }, "createdBy": { "type": "keyword" }, "enabled": { "type": "boolean" }, "executionStatus": { "properties": { "error": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } }, "lastDuration": { "type": "long" }, "lastExecutionDate": { "type": "date" }, "numberOfTriggeredActions": { "type": "long" }, "status": { "type": "keyword" }, "warning": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } } } }, "lastRun": { "properties": { "alertsCount": { "properties": { "active": { "type": "float" }, "ignored": { "type": "float" }, "new": { "type": "float" }, "recovered": { "type": "float" } } }, "outcome": { "type": "keyword" }, "outcomeOrder": { "type": "float" } } }, "legacyId": { "type": "keyword" }, "mapped_params": { "properties": { "risk_score": { "type": "float" }, "severity": { "type": "keyword" } } }, "monitoring": { "properties": { "run": { "properties": { "calculated_metrics": { "properties": { "p50": { "type": "long" }, "p95": { "type": "long" }, "p99": { "type": "long" }, "success_ratio": { "type": "float" } } }, "last_run": { "properties": { "metrics": { "properties": { "duration": { "type": "long" }, "gap_duration_s": { "type": "float" }, "total_alerts_created": { "type": "float" }, "total_alerts_detected": { "type": "float" }, "total_indexing_duration_ms": { "type": "long" }, "total_search_duration_ms": { "type": "long" } } }, "timestamp": { "type": "date" } } } } } } }, "muteAll": { "type": "boolean" }, "mutedInstanceIds": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "normalizer": "lowercase" } } }, "notifyWhen": { "type": "keyword" }, "params": { "type": "flattened", "ignore_above": 4096 }, "revision": { "type": "long" }, "running": { "type": "boolean" }, "schedule": { "properties": { "interval": { "type": "keyword" } } }, "scheduledTaskId": { "type": "keyword" }, "snoozeSchedule": { "type": "nested", "properties": { "duration": { "type": "long" }, "id": { "type": "keyword" }, "skipRecurrences": { "type": "date", "format": "strict_date_time" } } }, "tags": { "type": "keyword" }, "throttle": { "type": "keyword" }, "updatedAt": { "type": "date" }, "updatedBy": { "type": "keyword" } } }, "api_key_pending_invalidation": { "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" } } }, "cases": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "category": { "type": "keyword" }, "closed_at": { "type": "date" }, "closed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "connector": { "properties": { "fields": { "properties": { "key": { "type": "text" }, "value": { "type": "text" } } }, "name": { "type": "text" }, "type": { "type": "keyword" } } }, "created_at": { "type": "date" }, "created_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "customFields": { "type": "nested", "properties": { "key": { "type": "keyword" }, "type": { "type": "keyword" }, "value": { "type": "keyword", "fields": { "boolean": { "type": "boolean", "ignore_malformed": true }, "date": { "type": "date", "ignore_malformed": true }, "ip": { "type": "ip", "ignore_malformed": true }, "number": { "type": "long", "ignore_malformed": true }, "string": { "type": "text" } } } } }, "description": { "type": "text" }, "duration": { "type": "unsigned_long" }, "external_service": { "properties": { "connector_name": { "type": "keyword" }, "external_id": { "type": "keyword" }, "external_title": { "type": "text" }, "external_url": { "type": "text" }, "pushed_at": { "type": "date" }, "pushed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "incremental_id": { "type": "unsigned_long", "fields": { "raw": { "type": "keyword" } } }, "observables": { "type": "nested", "properties": { "typeKey": { "type": "keyword" }, "value": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "settings": { "properties": { "syncAlerts": { "type": "boolean" } } }, "severity": { "type": "short" }, "status": { "type": "short" }, "tags": { "type": "keyword" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "total_alerts": { "type": "integer" }, "total_comments": { "type": "integer" }, "updated_at": { "type": "date" }, "updated_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "cases-comments": { "dynamic": "false", "properties": { "actions": { "properties": { "type": { "type": "keyword" } } }, "alertId": { "type": "keyword" }, "comment": { "type": "text" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "externalReferenceAttachmentTypeId": { "type": "keyword" }, "owner": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "pushed_at": { "type": "date" }, "type": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-configure": { "dynamic": "false", "properties": { "closure_type": { "type": "keyword" }, "created_at": { "type": "date" }, "owner": { "type": "keyword" } } }, "cases-connector-mappings": { "dynamic": "false", "properties": { "owner": { "type": "keyword" } } }, "cases-incrementing-id": { "dynamic": "false", "properties": { "@timestamp": { "type": "date" }, "last_id": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-rules": { "dynamic": "false", "properties": { "counter": { "type": "unsigned_long" }, "createdAt": { "type": "date" }, "rules": { "properties": { "id": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "cases-telemetry": { "type": "object", "dynamic": "false" }, "cases-user-actions": { "dynamic": "false", "properties": { "action": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "payload": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "comment": { "properties": { "externalReferenceAttachmentTypeId": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "type": { "type": "keyword" } } }, "connector": { "properties": { "type": { "type": "keyword" } } } } }, "type": { "type": "keyword" } } }, "connector_token": { "dynamic": "false", "properties": { "connectorId": { "type": "keyword" }, "tokenType": { "type": "keyword" } } }, "coreMigrationVersion": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "type": "keyword" }, "maintenance-window": { "dynamic": "false", "properties": { "enabled": { "type": "boolean" }, "events": { "type": "date_range", "format": "epoch_millis||strict_date_optional_time" }, "expirationDate": { "type": "date" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "managed": { "type": "boolean" }, "namespace": { "type": "keyword" }, "namespaces": { "type": "keyword" }, "originId": { "type": "keyword" }, "references": { "type": "nested", "properties": { "id": { "type": "keyword" }, "name": { "type": "keyword" }, "type": { "type": "keyword" } } }, "rules-settings": { "dynamic": "false", "properties": { "flapping": { "type": "object" } } }, "scheduled_report": { "dynamic": "false", "properties": { "createdBy": { "type": "keyword" } } }, "type": { "type": "keyword" }, "typeMigrationVersion": { "type": "version" }, "updated_at": { "type": "date" }, "updated_by": { "type": "keyword" } } } ``` </details> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... --------- Co-authored-by: Jan Monschke <jan.monschke@elastic.co> Co-authored-by: Michael Olorunnisola <michael.olorunnisola@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary This PR updates the mapping for the `incremental_id` field to be a [mulit-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field). In the initial implementation with just `unsigned_long`, running search when combining this field with non-numeric fields such as `keyword` didn't function due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use). The main concern for this change is initializing a mapping change in the serverless environment, but this was tested against [this PR](#230278) that also enables the functionality that will populate this field. For testing: see #230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
### TLDR We need to utilize `text` in place of `keyword` to not break phrase prefix queries, so introducing the field `incremental_id.text` ### Background A new issue appeared where the current search field `title` and `description` are of mapping type text. This typically shouldn't be a problem, but unfortunately when attempting to run a prefixed query with the new `incremental_id.keyword` field in [this pr](#230278) we received the following error: To test, run [this test](https://github.com/elastic/kibana/blob/8ffa408f560b59cde8f045ff440090a05bf7bdbf/x-pack/platform/test/functional_with_es_ssl/apps/cases/group2/list_view.ts#L397) on [this PR](#230278) (after changing all instances in the UI from `incremental_id.text` back to `incremental_id.keyword`: ``` search_phase_execution_exception Root causes: query_shard_exception: failed to create query: Can only use phrase prefix queries on text fields - not on [cases.incremental_id.keyword] which is of type [keyword] ``` After some digging as to exactly why this was happening, the only documentation regarding this we could find was in this comment: #129424 (comment) . We should most likely add this information to the documentation here as well: https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-prefix-query ? For historical reference of mapping changes to the `incremental_id` see: #234054 The primary concern for this change is initializing a mapping change in the serverless environment, but this has been tested in this pr and tested against [this PR](#230278) that also enables the functionality that will populate this field. CI has also been run to make sure all tests pass with the new mapping to avoid any additional surprises [here](#230278 (comment)) For testing: see #230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary This is a reversion of the revert of this original #228002 of incremental id work. This original revert was done, due to the search functionality in cases being broken when searching on the new `incremental_id` field. It being of type `unsigned_long` meant that ES would not return when it was included alongside text values due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use).. Rather than creating a new field, and making the existing `incremental_id` field dead weight, we instead [update it to a multi-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field), so we can search on this value as text alongside other cases values. The update of the mapping was done here: #234054 #### Functional Changes From Reversion 1. Use of `incremental_id.text` in search functionality in place of `incremental_id` 2. There is no longer an advanced setting to hide the feature in the UI as we feel comfortable releasing it as is, and the field is currently only metadata and doesn't introduce any functional changes outside of searching. ## Testing: Feature Flag: `xpack.cases.incrementalId.enabled: true`. Currently disabled and will be enabled after additional testing during FF When running a clean branch, the feature will work correctly. We've verified locally that the mapping update works successfully via the methods described below, but feel free to test as well to confirm our results 👍🏾 ### Serverless 1. Create a security serverless environment via `qaf`. 4. Create cases in the serverless environment 5. Update images to the build image from this pr via the `--kb-docker-images` flag. 6. Wait for the task to run, and verify the numeric ids are applied to the cases 7. Search for cases by then numeric id via `#{incremental_id value}` and also search for `description + {incremental_id value}` and make sure the query successfully returns ### On-Prem 1. Run main locally 2. Create cases in the local environment 3. Switch branches from main to this branch 4. Wait for the task to run, and verify the numeric ids are applied to the cases 5. Search for cases by then numeric id via `#{id number}` and also search for `description + id number` and make sure the query successfully returns ## OUTDATED The below details were provided for manually updating the mapping via dev tools for testing/validation purposes This PR updates the mapping directly. Here are steps to update the mapping manually in a local instance: 0. Remove changes in `packages/kbn-check-mappings-update-cli/current_mappings.json` 1. Create some tests (there could be error toasts because `incremental_id.text` is not yet created 8. Create an `admin` user and assign `system_indices_superuser` and `superuser` role 9. Go to Dev tools, get the current mapping `GET /.kibana_alerting_cases_9.2.0_001/_mapping` 10. Add `text` as multi-field for `incremental_id` 11. Run `POST /.kibana_alerting_cases_9.2.0_001/_update_by_query` to update existing document 12. Go to Cases and observe the case id can be searched individually or in combination of other texts <details> <summary>mapping update query</summary> ``` PUT /.kibana_alerting_cases_9.2.0_001/_mapping { "properties": { "action": { "dynamic": "false", "properties": { "actionTypeId": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } }, "action_task_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" } } }, "ad_hoc_run_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" }, "end": { "type": "date" }, "rule": { "properties": { "alertTypeId": { "type": "keyword" }, "consumer": { "type": "keyword" } } }, "start": { "type": "date" } } }, "alert": { "dynamic": "false", "properties": { "actions": { "type": "nested", "dynamic": "false", "properties": { "actionRef": { "type": "keyword" }, "actionTypeId": { "type": "keyword" }, "group": { "type": "keyword" } } }, "alertTypeId": { "type": "keyword" }, "artifacts": { "properties": { "investigation_guide": { "properties": { "blob": { "type": "text" } } } } }, "consumer": { "type": "keyword" }, "createdAt": { "type": "date" }, "createdBy": { "type": "keyword" }, "enabled": { "type": "boolean" }, "executionStatus": { "properties": { "error": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } }, "lastDuration": { "type": "long" }, "lastExecutionDate": { "type": "date" }, "numberOfTriggeredActions": { "type": "long" }, "status": { "type": "keyword" }, "warning": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } } } }, "lastRun": { "properties": { "alertsCount": { "properties": { "active": { "type": "float" }, "ignored": { "type": "float" }, "new": { "type": "float" }, "recovered": { "type": "float" } } }, "outcome": { "type": "keyword" }, "outcomeOrder": { "type": "float" } } }, "legacyId": { "type": "keyword" }, "mapped_params": { "properties": { "risk_score": { "type": "float" }, "severity": { "type": "keyword" } } }, "monitoring": { "properties": { "run": { "properties": { "calculated_metrics": { "properties": { "p50": { "type": "long" }, "p95": { "type": "long" }, "p99": { "type": "long" }, "success_ratio": { "type": "float" } } }, "last_run": { "properties": { "metrics": { "properties": { "duration": { "type": "long" }, "gap_duration_s": { "type": "float" }, "total_alerts_created": { "type": "float" }, "total_alerts_detected": { "type": "float" }, "total_indexing_duration_ms": { "type": "long" }, "total_search_duration_ms": { "type": "long" } } }, "timestamp": { "type": "date" } } } } } } }, "muteAll": { "type": "boolean" }, "mutedInstanceIds": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "normalizer": "lowercase" } } }, "notifyWhen": { "type": "keyword" }, "params": { "type": "flattened", "ignore_above": 4096 }, "revision": { "type": "long" }, "running": { "type": "boolean" }, "schedule": { "properties": { "interval": { "type": "keyword" } } }, "scheduledTaskId": { "type": "keyword" }, "snoozeSchedule": { "type": "nested", "properties": { "duration": { "type": "long" }, "id": { "type": "keyword" }, "skipRecurrences": { "type": "date", "format": "strict_date_time" } } }, "tags": { "type": "keyword" }, "throttle": { "type": "keyword" }, "updatedAt": { "type": "date" }, "updatedBy": { "type": "keyword" } } }, "api_key_pending_invalidation": { "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" } } }, "cases": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "category": { "type": "keyword" }, "closed_at": { "type": "date" }, "closed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "connector": { "properties": { "fields": { "properties": { "key": { "type": "text" }, "value": { "type": "text" } } }, "name": { "type": "text" }, "type": { "type": "keyword" } } }, "created_at": { "type": "date" }, "created_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "customFields": { "type": "nested", "properties": { "key": { "type": "keyword" }, "type": { "type": "keyword" }, "value": { "type": "keyword", "fields": { "boolean": { "type": "boolean", "ignore_malformed": true }, "date": { "type": "date", "ignore_malformed": true }, "ip": { "type": "ip", "ignore_malformed": true }, "number": { "type": "long", "ignore_malformed": true }, "string": { "type": "text" } } } } }, "description": { "type": "text" }, "duration": { "type": "unsigned_long" }, "external_service": { "properties": { "connector_name": { "type": "keyword" }, "external_id": { "type": "keyword" }, "external_title": { "type": "text" }, "external_url": { "type": "text" }, "pushed_at": { "type": "date" }, "pushed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "incremental_id": { "type": "unsigned_long", "fields": { "raw": { "type": "keyword" } } }, "observables": { "type": "nested", "properties": { "typeKey": { "type": "keyword" }, "value": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "settings": { "properties": { "syncAlerts": { "type": "boolean" } } }, "severity": { "type": "short" }, "status": { "type": "short" }, "tags": { "type": "keyword" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "total_alerts": { "type": "integer" }, "total_comments": { "type": "integer" }, "updated_at": { "type": "date" }, "updated_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "cases-comments": { "dynamic": "false", "properties": { "actions": { "properties": { "type": { "type": "keyword" } } }, "alertId": { "type": "keyword" }, "comment": { "type": "text" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "externalReferenceAttachmentTypeId": { "type": "keyword" }, "owner": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "pushed_at": { "type": "date" }, "type": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-configure": { "dynamic": "false", "properties": { "closure_type": { "type": "keyword" }, "created_at": { "type": "date" }, "owner": { "type": "keyword" } } }, "cases-connector-mappings": { "dynamic": "false", "properties": { "owner": { "type": "keyword" } } }, "cases-incrementing-id": { "dynamic": "false", "properties": { "@timestamp": { "type": "date" }, "last_id": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-rules": { "dynamic": "false", "properties": { "counter": { "type": "unsigned_long" }, "createdAt": { "type": "date" }, "rules": { "properties": { "id": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "cases-telemetry": { "type": "object", "dynamic": "false" }, "cases-user-actions": { "dynamic": "false", "properties": { "action": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "payload": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "comment": { "properties": { "externalReferenceAttachmentTypeId": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "type": { "type": "keyword" } } }, "connector": { "properties": { "type": { "type": "keyword" } } } } }, "type": { "type": "keyword" } } }, "connector_token": { "dynamic": "false", "properties": { "connectorId": { "type": "keyword" }, "tokenType": { "type": "keyword" } } }, "coreMigrationVersion": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "type": "keyword" }, "maintenance-window": { "dynamic": "false", "properties": { "enabled": { "type": "boolean" }, "events": { "type": "date_range", "format": "epoch_millis||strict_date_optional_time" }, "expirationDate": { "type": "date" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "managed": { "type": "boolean" }, "namespace": { "type": "keyword" }, "namespaces": { "type": "keyword" }, "originId": { "type": "keyword" }, "references": { "type": "nested", "properties": { "id": { "type": "keyword" }, "name": { "type": "keyword" }, "type": { "type": "keyword" } } }, "rules-settings": { "dynamic": "false", "properties": { "flapping": { "type": "object" } } }, "scheduled_report": { "dynamic": "false", "properties": { "createdBy": { "type": "keyword" } } }, "type": { "type": "keyword" }, "typeMigrationVersion": { "type": "version" }, "updated_at": { "type": "date" }, "updated_by": { "type": "keyword" } } } ``` </details> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... --------- Co-authored-by: Jan Monschke <jan.monschke@elastic.co> Co-authored-by: Michael Olorunnisola <michael.olorunnisola@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary This is a reversion of the revert of this original elastic#228002 of incremental id work. This original revert was done, due to the search functionality in cases being broken when searching on the new `incremental_id` field. It being of type `unsigned_long` meant that ES would not return when it was included alongside text values due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use).. Rather than creating a new field, and making the existing `incremental_id` field dead weight, we instead [update it to a multi-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field), so we can search on this value as text alongside other cases values. The update of the mapping was done here: elastic#234054 #### Functional Changes From Reversion 1. Use of `incremental_id.text` in search functionality in place of `incremental_id` 2. There is no longer an advanced setting to hide the feature in the UI as we feel comfortable releasing it as is, and the field is currently only metadata and doesn't introduce any functional changes outside of searching. ## Testing: Feature Flag: `xpack.cases.incrementalId.enabled: true`. Currently disabled and will be enabled after additional testing during FF When running a clean branch, the feature will work correctly. We've verified locally that the mapping update works successfully via the methods described below, but feel free to test as well to confirm our results 👍🏾 ### Serverless 1. Create a security serverless environment via `qaf`. 4. Create cases in the serverless environment 5. Update images to the build image from this pr via the `--kb-docker-images` flag. 6. Wait for the task to run, and verify the numeric ids are applied to the cases 7. Search for cases by then numeric id via `#{incremental_id value}` and also search for `description + {incremental_id value}` and make sure the query successfully returns ### On-Prem 1. Run main locally 2. Create cases in the local environment 3. Switch branches from main to this branch 4. Wait for the task to run, and verify the numeric ids are applied to the cases 5. Search for cases by then numeric id via `#{id number}` and also search for `description + id number` and make sure the query successfully returns ## OUTDATED The below details were provided for manually updating the mapping via dev tools for testing/validation purposes This PR updates the mapping directly. Here are steps to update the mapping manually in a local instance: 0. Remove changes in `packages/kbn-check-mappings-update-cli/current_mappings.json` 1. Create some tests (there could be error toasts because `incremental_id.text` is not yet created 8. Create an `admin` user and assign `system_indices_superuser` and `superuser` role 9. Go to Dev tools, get the current mapping `GET /.kibana_alerting_cases_9.2.0_001/_mapping` 10. Add `text` as multi-field for `incremental_id` 11. Run `POST /.kibana_alerting_cases_9.2.0_001/_update_by_query` to update existing document 12. Go to Cases and observe the case id can be searched individually or in combination of other texts <details> <summary>mapping update query</summary> ``` PUT /.kibana_alerting_cases_9.2.0_001/_mapping { "properties": { "action": { "dynamic": "false", "properties": { "actionTypeId": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } }, "action_task_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" } } }, "ad_hoc_run_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" }, "end": { "type": "date" }, "rule": { "properties": { "alertTypeId": { "type": "keyword" }, "consumer": { "type": "keyword" } } }, "start": { "type": "date" } } }, "alert": { "dynamic": "false", "properties": { "actions": { "type": "nested", "dynamic": "false", "properties": { "actionRef": { "type": "keyword" }, "actionTypeId": { "type": "keyword" }, "group": { "type": "keyword" } } }, "alertTypeId": { "type": "keyword" }, "artifacts": { "properties": { "investigation_guide": { "properties": { "blob": { "type": "text" } } } } }, "consumer": { "type": "keyword" }, "createdAt": { "type": "date" }, "createdBy": { "type": "keyword" }, "enabled": { "type": "boolean" }, "executionStatus": { "properties": { "error": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } }, "lastDuration": { "type": "long" }, "lastExecutionDate": { "type": "date" }, "numberOfTriggeredActions": { "type": "long" }, "status": { "type": "keyword" }, "warning": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } } } }, "lastRun": { "properties": { "alertsCount": { "properties": { "active": { "type": "float" }, "ignored": { "type": "float" }, "new": { "type": "float" }, "recovered": { "type": "float" } } }, "outcome": { "type": "keyword" }, "outcomeOrder": { "type": "float" } } }, "legacyId": { "type": "keyword" }, "mapped_params": { "properties": { "risk_score": { "type": "float" }, "severity": { "type": "keyword" } } }, "monitoring": { "properties": { "run": { "properties": { "calculated_metrics": { "properties": { "p50": { "type": "long" }, "p95": { "type": "long" }, "p99": { "type": "long" }, "success_ratio": { "type": "float" } } }, "last_run": { "properties": { "metrics": { "properties": { "duration": { "type": "long" }, "gap_duration_s": { "type": "float" }, "total_alerts_created": { "type": "float" }, "total_alerts_detected": { "type": "float" }, "total_indexing_duration_ms": { "type": "long" }, "total_search_duration_ms": { "type": "long" } } }, "timestamp": { "type": "date" } } } } } } }, "muteAll": { "type": "boolean" }, "mutedInstanceIds": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "normalizer": "lowercase" } } }, "notifyWhen": { "type": "keyword" }, "params": { "type": "flattened", "ignore_above": 4096 }, "revision": { "type": "long" }, "running": { "type": "boolean" }, "schedule": { "properties": { "interval": { "type": "keyword" } } }, "scheduledTaskId": { "type": "keyword" }, "snoozeSchedule": { "type": "nested", "properties": { "duration": { "type": "long" }, "id": { "type": "keyword" }, "skipRecurrences": { "type": "date", "format": "strict_date_time" } } }, "tags": { "type": "keyword" }, "throttle": { "type": "keyword" }, "updatedAt": { "type": "date" }, "updatedBy": { "type": "keyword" } } }, "api_key_pending_invalidation": { "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" } } }, "cases": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "category": { "type": "keyword" }, "closed_at": { "type": "date" }, "closed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "connector": { "properties": { "fields": { "properties": { "key": { "type": "text" }, "value": { "type": "text" } } }, "name": { "type": "text" }, "type": { "type": "keyword" } } }, "created_at": { "type": "date" }, "created_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "customFields": { "type": "nested", "properties": { "key": { "type": "keyword" }, "type": { "type": "keyword" }, "value": { "type": "keyword", "fields": { "boolean": { "type": "boolean", "ignore_malformed": true }, "date": { "type": "date", "ignore_malformed": true }, "ip": { "type": "ip", "ignore_malformed": true }, "number": { "type": "long", "ignore_malformed": true }, "string": { "type": "text" } } } } }, "description": { "type": "text" }, "duration": { "type": "unsigned_long" }, "external_service": { "properties": { "connector_name": { "type": "keyword" }, "external_id": { "type": "keyword" }, "external_title": { "type": "text" }, "external_url": { "type": "text" }, "pushed_at": { "type": "date" }, "pushed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "incremental_id": { "type": "unsigned_long", "fields": { "raw": { "type": "keyword" } } }, "observables": { "type": "nested", "properties": { "typeKey": { "type": "keyword" }, "value": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "settings": { "properties": { "syncAlerts": { "type": "boolean" } } }, "severity": { "type": "short" }, "status": { "type": "short" }, "tags": { "type": "keyword" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "total_alerts": { "type": "integer" }, "total_comments": { "type": "integer" }, "updated_at": { "type": "date" }, "updated_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "cases-comments": { "dynamic": "false", "properties": { "actions": { "properties": { "type": { "type": "keyword" } } }, "alertId": { "type": "keyword" }, "comment": { "type": "text" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "externalReferenceAttachmentTypeId": { "type": "keyword" }, "owner": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "pushed_at": { "type": "date" }, "type": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-configure": { "dynamic": "false", "properties": { "closure_type": { "type": "keyword" }, "created_at": { "type": "date" }, "owner": { "type": "keyword" } } }, "cases-connector-mappings": { "dynamic": "false", "properties": { "owner": { "type": "keyword" } } }, "cases-incrementing-id": { "dynamic": "false", "properties": { "@timestamp": { "type": "date" }, "last_id": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-rules": { "dynamic": "false", "properties": { "counter": { "type": "unsigned_long" }, "createdAt": { "type": "date" }, "rules": { "properties": { "id": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "cases-telemetry": { "type": "object", "dynamic": "false" }, "cases-user-actions": { "dynamic": "false", "properties": { "action": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "payload": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "comment": { "properties": { "externalReferenceAttachmentTypeId": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "type": { "type": "keyword" } } }, "connector": { "properties": { "type": { "type": "keyword" } } } } }, "type": { "type": "keyword" } } }, "connector_token": { "dynamic": "false", "properties": { "connectorId": { "type": "keyword" }, "tokenType": { "type": "keyword" } } }, "coreMigrationVersion": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "type": "keyword" }, "maintenance-window": { "dynamic": "false", "properties": { "enabled": { "type": "boolean" }, "events": { "type": "date_range", "format": "epoch_millis||strict_date_optional_time" }, "expirationDate": { "type": "date" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "managed": { "type": "boolean" }, "namespace": { "type": "keyword" }, "namespaces": { "type": "keyword" }, "originId": { "type": "keyword" }, "references": { "type": "nested", "properties": { "id": { "type": "keyword" }, "name": { "type": "keyword" }, "type": { "type": "keyword" } } }, "rules-settings": { "dynamic": "false", "properties": { "flapping": { "type": "object" } } }, "scheduled_report": { "dynamic": "false", "properties": { "createdBy": { "type": "keyword" } } }, "type": { "type": "keyword" }, "typeMigrationVersion": { "type": "version" }, "updated_at": { "type": "date" }, "updated_by": { "type": "keyword" } } } ``` </details> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... --------- Co-authored-by: Jan Monschke <jan.monschke@elastic.co> Co-authored-by: Michael Olorunnisola <michael.olorunnisola@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
### TLDR We need to utilize `text` in place of `keyword` to not break phrase prefix queries, so introducing the field `incremental_id.text` ### Background A new issue appeared where the current search field `title` and `description` are of mapping type text. This typically shouldn't be a problem, but unfortunately when attempting to run a prefixed query with the new `incremental_id.keyword` field in [this pr](elastic#230278) we received the following error: To test, run [this test](https://github.com/elastic/kibana/blob/4da9288e4d3f13e24e991f91cc51c3ef9fcf5bf7/x-pack/platform/test/functional_with_es_ssl/apps/cases/group2/list_view.ts#L397) on [this PR](elastic#230278) (after changing all instances in the UI from `incremental_id.text` back to `incremental_id.keyword`: ``` search_phase_execution_exception Root causes: query_shard_exception: failed to create query: Can only use phrase prefix queries on text fields - not on [cases.incremental_id.keyword] which is of type [keyword] ``` After some digging as to exactly why this was happening, the only documentation regarding this we could find was in this comment: elastic#129424 (comment) . We should most likely add this information to the documentation here as well: https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-prefix-query ? For historical reference of mapping changes to the `incremental_id` see: elastic#234054 The primary concern for this change is initializing a mapping change in the serverless environment, but this has been tested in this pr and tested against [this PR](elastic#230278) that also enables the functionality that will populate this field. CI has also been run to make sure all tests pass with the new mapping to avoid any additional surprises [here](elastic#230278 (comment)) For testing: see elastic#230278 (comment) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary This is a reversion of the revert of this original elastic#228002 of incremental id work. This original revert was done, due to the search functionality in cases being broken when searching on the new `incremental_id` field. It being of type `unsigned_long` meant that ES would not return when it was included alongside text values due to data type mismatch errors [described here](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/number#_which_type_should_i_use).. Rather than creating a new field, and making the existing `incremental_id` field dead weight, we instead [update it to a multi-field](https://www.elastic.co/docs/manage-data/data-store/mapping/update-mappings-examples#add-multi-fields-to-an-existing-field), so we can search on this value as text alongside other cases values. The update of the mapping was done here: elastic#234054 #### Functional Changes From Reversion 1. Use of `incremental_id.text` in search functionality in place of `incremental_id` 2. There is no longer an advanced setting to hide the feature in the UI as we feel comfortable releasing it as is, and the field is currently only metadata and doesn't introduce any functional changes outside of searching. ## Testing: Feature Flag: `xpack.cases.incrementalId.enabled: true`. Currently disabled and will be enabled after additional testing during FF When running a clean branch, the feature will work correctly. We've verified locally that the mapping update works successfully via the methods described below, but feel free to test as well to confirm our results 👍🏾 ### Serverless 1. Create a security serverless environment via `qaf`. 4. Create cases in the serverless environment 5. Update images to the build image from this pr via the `--kb-docker-images` flag. 6. Wait for the task to run, and verify the numeric ids are applied to the cases 7. Search for cases by then numeric id via `#{incremental_id value}` and also search for `description + {incremental_id value}` and make sure the query successfully returns ### On-Prem 1. Run main locally 2. Create cases in the local environment 3. Switch branches from main to this branch 4. Wait for the task to run, and verify the numeric ids are applied to the cases 5. Search for cases by then numeric id via `#{id number}` and also search for `description + id number` and make sure the query successfully returns ## OUTDATED The below details were provided for manually updating the mapping via dev tools for testing/validation purposes This PR updates the mapping directly. Here are steps to update the mapping manually in a local instance: 0. Remove changes in `packages/kbn-check-mappings-update-cli/current_mappings.json` 1. Create some tests (there could be error toasts because `incremental_id.text` is not yet created 8. Create an `admin` user and assign `system_indices_superuser` and `superuser` role 9. Go to Dev tools, get the current mapping `GET /.kibana_alerting_cases_9.2.0_001/_mapping` 10. Add `text` as multi-field for `incremental_id` 11. Run `POST /.kibana_alerting_cases_9.2.0_001/_update_by_query` to update existing document 12. Go to Cases and observe the case id can be searched individually or in combination of other texts <details> <summary>mapping update query</summary> ``` PUT /.kibana_alerting_cases_9.2.0_001/_mapping { "properties": { "action": { "dynamic": "false", "properties": { "actionTypeId": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } }, "action_task_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" } } }, "ad_hoc_run_params": { "dynamic": "false", "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" }, "end": { "type": "date" }, "rule": { "properties": { "alertTypeId": { "type": "keyword" }, "consumer": { "type": "keyword" } } }, "start": { "type": "date" } } }, "alert": { "dynamic": "false", "properties": { "actions": { "type": "nested", "dynamic": "false", "properties": { "actionRef": { "type": "keyword" }, "actionTypeId": { "type": "keyword" }, "group": { "type": "keyword" } } }, "alertTypeId": { "type": "keyword" }, "artifacts": { "properties": { "investigation_guide": { "properties": { "blob": { "type": "text" } } } } }, "consumer": { "type": "keyword" }, "createdAt": { "type": "date" }, "createdBy": { "type": "keyword" }, "enabled": { "type": "boolean" }, "executionStatus": { "properties": { "error": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } }, "lastDuration": { "type": "long" }, "lastExecutionDate": { "type": "date" }, "numberOfTriggeredActions": { "type": "long" }, "status": { "type": "keyword" }, "warning": { "properties": { "message": { "type": "keyword" }, "reason": { "type": "keyword" } } } } }, "lastRun": { "properties": { "alertsCount": { "properties": { "active": { "type": "float" }, "ignored": { "type": "float" }, "new": { "type": "float" }, "recovered": { "type": "float" } } }, "outcome": { "type": "keyword" }, "outcomeOrder": { "type": "float" } } }, "legacyId": { "type": "keyword" }, "mapped_params": { "properties": { "risk_score": { "type": "float" }, "severity": { "type": "keyword" } } }, "monitoring": { "properties": { "run": { "properties": { "calculated_metrics": { "properties": { "p50": { "type": "long" }, "p95": { "type": "long" }, "p99": { "type": "long" }, "success_ratio": { "type": "float" } } }, "last_run": { "properties": { "metrics": { "properties": { "duration": { "type": "long" }, "gap_duration_s": { "type": "float" }, "total_alerts_created": { "type": "float" }, "total_alerts_detected": { "type": "float" }, "total_indexing_duration_ms": { "type": "long" }, "total_search_duration_ms": { "type": "long" } } }, "timestamp": { "type": "date" } } } } } } }, "muteAll": { "type": "boolean" }, "mutedInstanceIds": { "type": "keyword" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "normalizer": "lowercase" } } }, "notifyWhen": { "type": "keyword" }, "params": { "type": "flattened", "ignore_above": 4096 }, "revision": { "type": "long" }, "running": { "type": "boolean" }, "schedule": { "properties": { "interval": { "type": "keyword" } } }, "scheduledTaskId": { "type": "keyword" }, "snoozeSchedule": { "type": "nested", "properties": { "duration": { "type": "long" }, "id": { "type": "keyword" }, "skipRecurrences": { "type": "date", "format": "strict_date_time" } } }, "tags": { "type": "keyword" }, "throttle": { "type": "keyword" }, "updatedAt": { "type": "date" }, "updatedBy": { "type": "keyword" } } }, "api_key_pending_invalidation": { "properties": { "apiKeyId": { "type": "keyword" }, "createdAt": { "type": "date" } } }, "cases": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "category": { "type": "keyword" }, "closed_at": { "type": "date" }, "closed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "connector": { "properties": { "fields": { "properties": { "key": { "type": "text" }, "value": { "type": "text" } } }, "name": { "type": "text" }, "type": { "type": "keyword" } } }, "created_at": { "type": "date" }, "created_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } }, "customFields": { "type": "nested", "properties": { "key": { "type": "keyword" }, "type": { "type": "keyword" }, "value": { "type": "keyword", "fields": { "boolean": { "type": "boolean", "ignore_malformed": true }, "date": { "type": "date", "ignore_malformed": true }, "ip": { "type": "ip", "ignore_malformed": true }, "number": { "type": "long", "ignore_malformed": true }, "string": { "type": "text" } } } } }, "description": { "type": "text" }, "duration": { "type": "unsigned_long" }, "external_service": { "properties": { "connector_name": { "type": "keyword" }, "external_id": { "type": "keyword" }, "external_title": { "type": "text" }, "external_url": { "type": "text" }, "pushed_at": { "type": "date" }, "pushed_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "incremental_id": { "type": "unsigned_long", "fields": { "raw": { "type": "keyword" } } }, "observables": { "type": "nested", "properties": { "typeKey": { "type": "keyword" }, "value": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "settings": { "properties": { "syncAlerts": { "type": "boolean" } } }, "severity": { "type": "short" }, "status": { "type": "short" }, "tags": { "type": "keyword" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "total_alerts": { "type": "integer" }, "total_comments": { "type": "integer" }, "updated_at": { "type": "date" }, "updated_by": { "properties": { "email": { "type": "keyword" }, "full_name": { "type": "keyword" }, "profile_uid": { "type": "keyword" }, "username": { "type": "keyword" } } } } }, "cases-comments": { "dynamic": "false", "properties": { "actions": { "properties": { "type": { "type": "keyword" } } }, "alertId": { "type": "keyword" }, "comment": { "type": "text" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "externalReferenceAttachmentTypeId": { "type": "keyword" }, "owner": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "pushed_at": { "type": "date" }, "type": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-configure": { "dynamic": "false", "properties": { "closure_type": { "type": "keyword" }, "created_at": { "type": "date" }, "owner": { "type": "keyword" } } }, "cases-connector-mappings": { "dynamic": "false", "properties": { "owner": { "type": "keyword" } } }, "cases-incrementing-id": { "dynamic": "false", "properties": { "@timestamp": { "type": "date" }, "last_id": { "type": "keyword" }, "updated_at": { "type": "date" } } }, "cases-rules": { "dynamic": "false", "properties": { "counter": { "type": "unsigned_long" }, "createdAt": { "type": "date" }, "rules": { "properties": { "id": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "cases-telemetry": { "type": "object", "dynamic": "false" }, "cases-user-actions": { "dynamic": "false", "properties": { "action": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "properties": { "username": { "type": "keyword" } } }, "owner": { "type": "keyword" }, "payload": { "dynamic": "false", "properties": { "assignees": { "properties": { "uid": { "type": "keyword" } } }, "comment": { "properties": { "externalReferenceAttachmentTypeId": { "type": "keyword" }, "persistableStateAttachmentTypeId": { "type": "keyword" }, "type": { "type": "keyword" } } }, "connector": { "properties": { "type": { "type": "keyword" } } } } }, "type": { "type": "keyword" } } }, "connector_token": { "dynamic": "false", "properties": { "connectorId": { "type": "keyword" }, "tokenType": { "type": "keyword" } } }, "coreMigrationVersion": { "type": "keyword" }, "created_at": { "type": "date" }, "created_by": { "type": "keyword" }, "maintenance-window": { "dynamic": "false", "properties": { "enabled": { "type": "boolean" }, "events": { "type": "date_range", "format": "epoch_millis||strict_date_optional_time" }, "expirationDate": { "type": "date" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "updatedAt": { "type": "date" } } }, "managed": { "type": "boolean" }, "namespace": { "type": "keyword" }, "namespaces": { "type": "keyword" }, "originId": { "type": "keyword" }, "references": { "type": "nested", "properties": { "id": { "type": "keyword" }, "name": { "type": "keyword" }, "type": { "type": "keyword" } } }, "rules-settings": { "dynamic": "false", "properties": { "flapping": { "type": "object" } } }, "scheduled_report": { "dynamic": "false", "properties": { "createdBy": { "type": "keyword" } } }, "type": { "type": "keyword" }, "typeMigrationVersion": { "type": "version" }, "updated_at": { "type": "date" }, "updated_by": { "type": "keyword" } } } ``` </details> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... --------- Co-authored-by: Jan Monschke <jan.monschke@elastic.co> Co-authored-by: Michael Olorunnisola <michael.olorunnisola@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Summary
This PR updates the mapping for the
incremental_idfield to be a mulit-field. In the initial implementation with justunsigned_long, running search when combining this field with non-numeric fields such askeyworddidn't function due to data type mismatch errors described here.The main concern for this change is initializing a mapping change in the serverless environment, but this was tested against this PR that also enables the functionality that will populate this field.
For testing: see #230278 (comment)