Skip to content

CMR-10891: add wildcard type fields support for search behind feature flag#2415

Open
zimzoom wants to merge 1 commit intomasterfrom
CMR-10891
Open

CMR-10891: add wildcard type fields support for search behind feature flag#2415
zimzoom wants to merge 1 commit intomasterfrom
CMR-10891

Conversation

@zimzoom
Copy link
Copy Markdown
Contributor

@zimzoom zimzoom commented Apr 24, 2026

Overview

What is the objective?

Adds support for using Elasticsearch wildcard-type fields for granule wildcard searches, gated behind a feature flag so the behavior can be enabled only after the relevant indices are reindexed.

What are the changes?

  • Add feature flag defconfig enable-wildcard-field-searches -- when enabled, granule pattern searches now target dedicated wildcard fields for granule-ur and producer-granule-id, with separate case-sensitive and lowercase mappings. When the flag is disabled, wildcard searches continue using the existing standard fields, preserving prior behavior. Exact non-pattern searches are unchanged.

  • Adds wildcard-field mapping helpers in elastic-utils-lib, granule-specific wildcard mappings in search-app, and unit coverage for enabled and disabled toggle behavior, including readable granule name handling.

What areas of the application does this impact?

search-app, elastic-utils-lib

Required Checklist

  • [x ] New and existing unit and int tests pass locally and remotely
  • [x ] clj-kondo has been run locally and all errors in changed files are corrected
  • [x ] I have commented my code, particularly in hard-to-understand areas
  • I have made changes to the documentation (if necessary)
  • [x ] My changes generate no new warnings

Additional Checklist

  • I have removed unnecessary/dead code and imports in files I have changed
  • I have cleaned up integration tests by doing one or more of the following:
    • migrated any are2 tests to are3 in files I have changed
    • de-duped, consolidated, removed dead int tests
    • transformed applicable int tests into unit tests
    • reduced number of system state resets by updating fixtures. Ex) (use-fixtures :each (ingest/reset-fixture {})) to be :once instead of :each

Summary by CodeRabbit

  • New Features

    • Added a configurable option (disabled by default) to use dedicated wildcard fields for pattern searches, improving wildcard-search behavior.
    • Granule searches can now target these wildcard-specific field variants when the option is enabled.
  • Tests

    • Added unit tests verifying correct field selection for pattern vs exact granule searches and toggle behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

Introduces a boolean config to enable routing pattern-based (wildcard) string searches to dedicated Elasticsearch wildcard-type fields. Adds multimethods and resolvers for wildcard and lowercase-wildcard field mappings and updates StringCondition conversion to use them when the feature flag is enabled.

Changes

Cohort / File(s) Summary
Configuration
elastic-utils-lib/src/cmr/elastic_utils/config.clj
Added enable-wildcard-field-searches boolean config (default false).
Core Search Logic
elastic-utils-lib/src/cmr/elastic_utils/search/es_query_to_elastic.clj
Added multimethods field->wildcard-field-mappings and field->lowercase-wildcard-field-mappings and helper functions field->wildcard-field / field->lowercase-wildcard-field. Updated StringConditioncondition->elastic to use wildcard fields for pattern? queries when config is enabled.
Granule Field Mappings
search-app/src/cmr/search/data/query_to_elastic.clj
Added q2e multimethod specializations for :granule providing wildcard and lowercase-wildcard field mappings (e.g., :granule-ur, :producer-gran-id, :producer-granule-id).
Tests
search-app/test/cmr/search/test/unit/data/query_to_elastic_converters/granule_wildcard_fields.clj
New unit tests verifying exact vs pattern field selection, case-sensitive handling, readable-name wildcard behavior, and feature-flag toggling for wildcard-field searches.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant QueryProcessor as Query Processor
    participant FieldMapper as Field Mapper
    participant ES as Elasticsearch

    Client->>QueryProcessor: Submit StringCondition (pattern or exact)
    QueryProcessor->>QueryProcessor: Is pattern? Check and read config
    alt Pattern & Config Enabled
        QueryProcessor->>FieldMapper: Resolve wildcard field
        FieldMapper->>FieldMapper: Lookup wildcard / lowercase-wildcard mapping
        FieldMapper-->>QueryProcessor: Return wildcard field name
    else Non-pattern or Config Disabled
        QueryProcessor->>FieldMapper: Resolve standard field
        FieldMapper->>FieldMapper: Lookup keyword / lowercase mapping
        FieldMapper-->>QueryProcessor: Return standard field name
    end
    QueryProcessor->>ES: Send built query using selected field
    ES-->>Client: Return results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #2411: Adds wildcard-type granule fields to index mappings and indexing output (e.g., granule-ur-wildcard, producer-granule-id-wildcard) which this PR's search routing targets.

Suggested reviewers

  • rushgeo
  • jmaeng72
  • eereiter

Poem

🐰 Hopping through fields with a curious leap,

pattern hunts where keywords sleep,
A toggle set, the mappings sing,
Wildcards dance on elastic string,
Tests clap paws — the queries keep!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding wildcard type fields support for search behind a feature flag.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description follows the required template structure with all major sections completed: Overview (objective and changes), impacted areas, and required/additional checklists.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch CMR-10891

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@zimzoom zimzoom changed the title Cmr 10891 CMR-10891: add wildcard type fields support for search behind feature flag Apr 24, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
elastic-utils-lib/src/cmr/elastic_utils/config.clj (1)

106-112: Missing (declare enable-wildcard-field-searches) for consistency with file convention.

Every other defconfig in this file is preceded by a (declare …) form (e.g., lines 8, 20, 100). Add the matching declare to keep this file consistent and avoid clj-kondo warnings about forward references.

♻️ Proposed fix
+(declare enable-wildcard-field-searches)
 (defconfig enable-wildcard-field-searches
   "When true, pattern searches (wildcards) will use dedicated Elasticsearch
    wildcard-type fields for improved performance. When false, pattern searches
    will use the standard keyword fields. This should be enabled only after all
    indices have been reindexed to populate the wildcard fields."
   {:default false
    :type Boolean})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@elastic-utils-lib/src/cmr/elastic_utils/config.clj` around lines 106 - 112,
Add a forward declare for the defconfig symbol to match the file convention and
avoid clj-kondo warnings: insert a (declare enable-wildcard-field-searches)
immediately before the defconfig for enable-wildcard-field-searches so the
symbol is declared prior to its definition (consistent with other declarations
like the ones near lines 8, 20, 100).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@elastic-utils-lib/src/cmr/elastic_utils/config.clj`:
- Around line 106-112: Add a forward declare for the defconfig symbol to match
the file convention and avoid clj-kondo warnings: insert a (declare
enable-wildcard-field-searches) immediately before the defconfig for
enable-wildcard-field-searches so the symbol is declared prior to its definition
(consistent with other declarations like the ones near lines 8, 20, 100).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7ef0cb63-d675-445c-b273-d64f1d6d0611

📥 Commits

Reviewing files that changed from the base of the PR and between 44dff20 and b075eae.

📒 Files selected for processing (4)
  • elastic-utils-lib/src/cmr/elastic_utils/config.clj
  • elastic-utils-lib/src/cmr/elastic_utils/search/es_query_to_elastic.clj
  • search-app/src/cmr/search/data/query_to_elastic.clj
  • search-app/test/cmr/search/test/unit/data/query_to_elastic_converters/granule_wildcard_fields.clj


(defmethod field->wildcard-field-mappings :default
[_]
;; No wildcard field mappings specified by default
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment doesn't really add much

Copy link
Copy Markdown
Contributor Author

@zimzoom zimzoom Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment follows the style of the other default methods in this area of the code base

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you really like the comments you may keep them


(defmethod field->lowercase-wildcard-field-mappings :default
[_]
;; No lowercase wildcard field mappings specified by default
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment doesn't really add much

Copy link
Copy Markdown
Contributor Author

@zimzoom zimzoom Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment follows the style of the other default methods in this area of the code base

Comment thread elastic-utils-lib/src/cmr/elastic_utils/search/es_query_to_elastic.clj Outdated
(cond
case-sensitive? (field->wildcard-field concept-type field)
:else (field->lowercase-wildcard-field concept-type field))
;; Original behavior: use standard fields
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these comments don't add much

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments delineate a feature flag that will be removed soon

Comment thread search-app/src/cmr/search/data/query_to_elastic.clj Outdated
Comment thread elastic-utils-lib/src/cmr/elastic_utils/search/es_query_to_elastic.clj Outdated
@zimzoom zimzoom marked this pull request as draft April 24, 2026 18:02
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 33.33333% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.90%. Comparing base (44dff20) to head (0363c7e).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...c/cmr/elastic_utils/search/es_query_to_elastic.clj 33.33% 16 Missing ⚠️
...earch-app/src/cmr/search/data/query_to_elastic.clj 26.66% 11 Missing ⚠️
elastic-utils-lib/src/cmr/elastic_utils/config.clj 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2415   +/-   ##
=======================================
  Coverage   57.90%   57.90%           
=======================================
  Files        1067     1067           
  Lines       73475    73502   +27     
  Branches     2129     2127    -2     
=======================================
+ Hits        42544    42564   +20     
- Misses      28950    28953    +3     
- Partials     1981     1985    +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zimzoom zimzoom marked this pull request as ready for review April 27, 2026 13:49
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
search-app/test/cmr/search/test/unit/data/query_to_elastic_converters/granule_wildcard_fields.clj (1)

31-40: Consider adding test coverage for :producer-gran-id alias.

The wildcard field mappings define both :producer-gran-id and :producer-granule-id aliases (lines 313-314 and 319-320 in the implementation file), but the tests only exercise :producer-granule-id. Adding a test for :producer-gran-id would verify both aliases work correctly.

🧪 Suggested additional test cases
(testing "producer-gran-id alias uses same wildcard field"
  (is (= {:wildcard {"producer-granule-id-lowercase-wildcard" "prod*"}}
         (q2e/condition->elastic
          (qm/string-condition :producer-gran-id "Prod*" false true)
          :granule))))

(testing "producer-gran-id alias case-sensitive uses same wildcard field"
  (is (= {:wildcard {:producer-granule-id-wildcard "Prod*"}}
         (q2e/condition->elastic
          (qm/string-condition :producer-gran-id "Prod*" true true)
          :granule))))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@search-app/test/cmr/search/test/unit/data/query_to_elastic_converters/granule_wildcard_fields.clj`
around lines 31 - 40, Add parallel tests for the :producer-gran-id alias
mirroring the existing :producer-granule-id tests: call qm/string-condition with
:producer-gran-id and the same inputs used in the two tests (case-insensitive
and case-sensitive wildcard forms) and assert q2e/condition->elastic returns the
same wildcard maps ("producer-granule-id-lowercase-wildcard" for
case-insensitive and "producer-granule-id-wildcard" for case-sensitive) so both
aliases are covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@search-app/test/cmr/search/test/unit/data/query_to_elastic_converters/granule_wildcard_fields.clj`:
- Around line 31-40: Add parallel tests for the :producer-gran-id alias
mirroring the existing :producer-granule-id tests: call qm/string-condition with
:producer-gran-id and the same inputs used in the two tests (case-insensitive
and case-sensitive wildcard forms) and assert q2e/condition->elastic returns the
same wildcard maps ("producer-granule-id-lowercase-wildcard" for
case-insensitive and "producer-granule-id-wildcard" for case-sensitive) so both
aliases are covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 33262db1-9f98-42f8-84bc-e6da9784ecb5

📥 Commits

Reviewing files that changed from the base of the PR and between b075eae and 0363c7e.

📒 Files selected for processing (4)
  • elastic-utils-lib/src/cmr/elastic_utils/config.clj
  • elastic-utils-lib/src/cmr/elastic_utils/search/es_query_to_elastic.clj
  • search-app/src/cmr/search/data/query_to_elastic.clj
  • search-app/test/cmr/search/test/unit/data/query_to_elastic_converters/granule_wildcard_fields.clj
🚧 Files skipped from review as they are similar to previous changes (2)
  • elastic-utils-lib/src/cmr/elastic_utils/config.clj
  • elastic-utils-lib/src/cmr/elastic_utils/search/es_query_to_elastic.clj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants