[go: up one dir, main page]

Skip to content

Add ES DSL schema_versions implementation

What does this MR do and why?

Introduces Search::Elastic::Dsl::SchemaVersions, a new DSL module for declaring and resolving Elasticsearch schema versions inside DSL-based models.

This provides a declarative API to define version history directly within model definitions, replacing hard-coded constants or manual version checks.

It supports:

  • Static schema versions
  • Conditional versions (gated by feature flags or migration state)
  • Automatic resolution of the active version at runtime

Part of the Elasticsearch DSL powering Search::Elastic::Dsl::Models::<Model>.


Usage example

class Vulnerability
  include Search::Elastic::Dsl::SchemaVersions

  schema_versions do
    # Base version
    version 2525

    # Conditional version – only active when a migration or FF is ready
    version 2526, if: -> { migration_has_finished?(:vulnerability_index_upgrade) }

    # Feature-flag controlled version
    version 2527, if: -> { Feature.enabled?(:use_vulnerability_dsl_reference) }
  end
end

Vulnerability.current_version
# => returns the highest active version (2526 or 2527 if conditions true)

Each version(...) entry stores a version number and an optional condition proc. current_version automatically evaluates which versions are active and returns the latest one.


Implementation details

  • New file: ee/lib/search/elastic/dsl/schema_versions.rb

    • Adds the schema_versions and version DSL methods
    • Evaluates conditional versions dynamically at runtime
    • Tracks errors via Gitlab::ErrorTracking
    • Provides convenience alias schema_versioncurrent_version
  • Specs: ee/spec/lib/search/elastic/dsl/schema_versions_spec.rb

    • Covers unconditional and conditional version declarations
    • Tests fallback logic when no version is active
    • Verifies exception handling and error reporting

Architectural context

flowchart TD
    %% === BUILDERS LAYER ===
    subgraph BUILDERS["Search::Elastic::Dsl::Builders::*"]
        JB["JsonBuilder<br/>–––––––––––––––––––––––––––––––<br/>Builds Elasticsearch JSON documents for indexing.<br/>Applies field definitions, compute rules, and version filters."]
        MB["MappingBuilder<br/>–––––––––––––––––––––––––––––––<br/>Generates Elasticsearch mappings.<br/>Includes only fields active for the current schema version."]
        PB["ProxyBuilder<br/>–––––––––––––––––––––––––––––––<br/>Creates enriched runtime proxies combining raw records<br/>and preloaded enrichment data for indexing."]
        SB["SettingsBuilder<br/>–––––––––––––––––––––––––––––––<br/>Builds index settings including analyzers,<br/>tokenizers, and normalization filters."]
    end


    %% === CORE DSL LAYER ===
    subgraph CORE["Search::Elastic::Dsl::* (Core Modules)"]
        F["Field DSL<br/>–––––––––––––––––––––––––––––––<br/>Central definition of all fields:<br/>type, compute, preload, default, and conditions."]
        SV["SchemaVersions<br/>–––––––––––––––––––––––––––––––<br/>Defines available schema versions and<br/>resolves which one is currently active."]
        ST["Settings<br/>–––––––––––––––––––––––––––––––<br/>Defines reusable analyzer, filter,<br/>and tokenizer configuration for indices."]
    end


    %% === RELATIONSHIPS ===
    JB --> F
    JB --> SV
    MB --> F
    MB --> SV
    PB --> F
    SB --> ST


    %% === STYLING ===
    classDef builder fill:#e8f1ff,stroke:#3366cc,stroke-width:1px,color:#000;
    classDef core fill:#f2faff,stroke:#66b3ff,stroke-width:1px,color:#000;
    classDef title fill:none,stroke:none,font-weight:bold;

    class BUILDERS,JB,MB,PB,SB builder;
    class CORE,F,SV,ST core;

SchemaVersions integrates with:

  • MappingBuilder, which uses it to resolve the correct schema version for mapping definitions.
  • Other DSL modules (Field, Settings) that build version-aware index definitions.

References


Screenshots or screen recordings

Before After

How to set up and validate locally

  1. Include the DSL module in a temporary class:

    class TestModel
      include Search::Elastic::Dsl::SchemaVersions
    
      schema_versions do
        version 1
        version 2, if: -> { Feature.enabled?(:test_feature) }
      end
    end
  2. In Rails console, toggle the feature flag and check:

    TestModel.current_version
    # => 1 or 2 depending on the FF state
  3. Verify expected version resolution in MappingBuilder output.


MR acceptance checklist

Edited by Ugo Nnanna Okeadu

Merge request reports

Loading