Skip to content

A type-safe metamodel library for Elasticsearch in Kotlin that generates compile-time field definitions from Spring Data Elasticsearch document classes.

License

Notifications You must be signed in to change notification settings

ekino/Metalastic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

45 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Metalastic Logo

Metalastic

Type-safe metamodel generator for Elasticsearch in Kotlin. Automatically generates compile-time validated field accessors from Spring Data Elasticsearch documents.

GitHub Actions Maven Central License: MIT Java 21 Kotlin Spring Data ES


πŸ“š Documentation

πŸ‘‰ Read the full documentation at ekino.github.io/Metalastic


What is Metalastic?

Metalastic is a compile-time code generator that transforms your Spring Data Elasticsearch @Document classes into type-safe metamodels. It eliminates string-based field names and provides full IDE support for building Elasticsearch queries.

Why Use Metalastic?

  • 🚫 No more typos - Compile-time validation prevents "staus" β†’ "status" errors
  • πŸ” IDE autocomplete - Full IntelliSense for nested document structures
  • πŸ›‘οΈ Type safety - Compile-time verification of field types and relationships
  • πŸ“¦ Zero runtime overhead - All code generation happens at compile time
  • πŸ”„ Automatic refactoring - Rename fields once, queries update everywhere
  • ⚑ Optional Query DSL - Fluent API with innovative operator syntax

Learn more about features β†’

Quick Start

1. Add the Gradle Plugin

// build.gradle.kts
plugins {
    kotlin("jvm") version "2.2.21"
    id("com.google.devtools.ksp") version "2.3.2"
    id("com.ekino.oss.metalastic") version "1.1.0"
}

repositories {
    mavenCentral()
}

2. Build Your Project

./gradlew build

Metamodels are automatically generated in build/generated/ksp/main/kotlin/

3. Use Generated Metamodels

import com.example.MetaProduct.Companion.product

// Type-safe field access
product.title.path()          // "title"
product.category.name.path()  // "category.name"

// Use in queries
QueryBuilders.termQuery(product.status.path(), "ACTIVE")

Full Getting Started Guide β†’

Example: The Problem & Solution

Before: String-Based Field Names ❌

// Error-prone string literals
NativeSearchQuery query = new NativeSearchQueryBuilder()
    .withQuery(
        QueryBuilders.boolQuery()
            .must(QueryBuilders.termQuery("staus", "active"))  // ❌ Typo!
            .filter(QueryBuilders.rangeQuery("prcie").gte(100)) // ❌ Typo!
    )
    .build();

// No IDE support, no refactoring, errors found at runtime 😞

After: Type-Safe Metamodels βœ…

import com.example.MetaProduct.Companion.product

// Compile-time validated
val query = QueryBuilders.boolQuery()
    .must(QueryBuilders.termQuery(product.status.path(), "active"))
    .filter(QueryBuilders.rangeQuery(product.price.path()).gte(100))

// IDE autocomplete, refactoring support, compile-time safety πŸŽ‰

With Optional Query DSL ✨

import com.metalastic.dsl.*
import com.example.MetaProduct.Companion.product

val query = BoolQuery.of {
    boolQueryDsl {
        must + {
            product.title match "laptop"
            product.status term ProductStatus.ACTIVE
        }

        filter + {
            product.price range 500.0.fromInclusive()..2000.0
            product.category.name term "electronics"
        }
    }
}

More Examples β†’

Documentation

Getting Started

Core Concepts

Examples & Advanced Usage

Installation Options

Using Gradle Plugin (Recommended)

plugins {
    id("com.google.devtools.ksp") version "2.3.2"
    id("com.ekino.oss.metalastic") version "1.1.0"
}

Manual Dependencies

dependencies {
    implementation("com.ekino.oss:metalastic-core:1.1.0")
    ksp("com.ekino.oss:metalastic-processor:1.1.0")

    // Optional: Query DSL module
    implementation("com.ekino.oss:metalastic-elasticsearch-dsl:1.1.0")
}

Detailed installation instructions β†’

Version Compatibility

Spring Data ES Elasticsearch Metalastic Core Query DSL Artifact
6.0.x 8.18.x βœ… 1.1.0 metalastic-elasticsearch-dsl:1.1.0
5.4.x - 5.5.x 8.15.x - 8.18.x βœ… 1.1.0 metalastic-elasticsearch-dsl-5.5:1.1.0
5.0.x - 5.3.x 8.5.x - 8.13.x βœ… 1.1.0 metalastic-elasticsearch-dsl-5.3:1.1.0

Full compatibility matrix β†’

Key Features

Core Module (Required)

  • βœ… Type-safe field access with path() methods
  • βœ… Automatic dotted notation for nested structures
  • βœ… All Elasticsearch field types supported
  • βœ… MultiField support with inner fields
  • βœ… Circular reference handling
  • βœ… Centralized metamodels registry
  • βœ… Java & Kotlin compatible

Query DSL Module (Optional)

  • βœ… Innovative clause + { } operator syntax
  • βœ… Mathematical notation for ranges (10.fromInclusive()..100)
  • βœ… Type-safe nested queries
  • βœ… Automatic value conversion (dates, enums, collections)
  • βœ… Full Elasticsearch query type support

Explore all features β†’

Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes following our code style:
    ./gradlew spotlessApply  # Format code
    ./gradlew check          # Run all checks
  4. Commit your changes: git commit -m 'Add amazing feature'
  5. Push to your branch: git push origin feature/amazing-feature
  6. Open a Pull Request

Code Style:

Development guide β†’

Building from Source

git clone https://github.com/ekino/Metalastic.git
cd Metalastic
./gradlew build

Support & Community

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Copyright Β© 2025 ekino


Ready to eliminate string-based field names?

Get Started β†’

About

A type-safe metamodel library for Elasticsearch in Kotlin that generates compile-time field definitions from Spring Data Elasticsearch document classes.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •