Skip to content

direct-democracy-solutions/elasticsearch-migration

Repository files navigation


Elastic Migrate

A migration tool for Elasticsearch/OpenSearch. This package helps you manage your Elasticsearch indices and mappings with ease.

🚀 Installation

npm install @direct-democracy-solutions/elasticsearch-migration

⚡️ Usage

1. Create a New Migration

npx es-migrate create <migration-name>

This command creates a new migration file. For example:

npx es-migrate create create_users_index

2. Run Migrations

npx es-migrate up

Applies all pending migrations in order.


Running from a CommonJS project

es-migrate runs and expects ESM. If you have a CommonJS project and wish to run es-migrate, pass an ESM loader to Node explicitly:

node --loader ts-node/esm node_modules/@ahmetkasap/elasticsearch-migration/dist/cli.js

tsx might work but hasn't been tested.

Your migrations should have the .mts or .mjs file extensions, not .ts.

3. Check Migration Status

npx es-migrate status

Displays the status of all migrations.


4. List Indices

npx es-migrate list-indices

Lists all indices in your Elasticsearch cluster.


5. Show Alias Information

npx es-migrate alias-info

Displays detailed information about index aliases.


6. Rollback Last Migration

npx es-migrate down

Reverts the last applied migration (rollback).


⚙️ Configuration

You can configure the tool using environment variables:

# Elasticsearch connection details
ELASTIC_SEARCH_NODE=http://127.0.0.1:9200
ELASTIC_SEARCH_USERNAME=elastic
ELASTIC_SEARCH_PASSWORD=password

# Directory for migration files
MIGRATIONS_PATH=./migrations

📝 Example Migration File

import { Client } from "@opensearch-project/opensearch";
import type { IMigration } from "@direct-democracy-solutions/elasticsearch-migration";

const migration: IMigration = {
  name: "create_users_index",
  timestamp: 1703123456789,

  async up(client: Client): Promise<void> {
    await client.indices.create({
      index: "users",
      body: {
        mappings: {
          properties: {
            name: { type: "text" },
            email: { type: "keyword" },
            age: { type: "integer" },
          },
        },
      },
    });
    console.log("Users index created successfully");
  },

  async down(client: Client): Promise<void> {
    await client.indices.delete({
      index: "users",
    });
    console.log("Users index deleted successfully");
  },
};

export default migration;

⚠️ TypeScript/Node.js Compatibility

For an effortless runtime experience on recent versions of Node, restrict your migrations to use only erasable syntax.

If you want to enforce this automatically, set the erasableSyntaxOnly option in tsconfig.json.

Node 22.6 or later with all erasable syntax

TypeScript migrations with no erasable syntax work out of the box on Node v22.18.0 or later.

To run TypeScript migrations on Node versions v22.6-v22.17, Invoke Node with --experimental-strip-types:

npx --node-options='--experimental-strip-types' es-migrate up

Node 22.7 or later with non-erasable syntax

To run TypeScript migrations with non-erasable syntax on v22.7.0 or later, invoke Node with --experimental-transform-types:

npx --node-options='--experimental-strip-types' es-migrate up

All supported Node versions

If neither of the above options is available to you, there is always tsx or ts-node:

npm i -D tsx
tsx es-migrate up

Or, you can write your migrations in JavaScript.


🧑‍💻 Programmatic Usage

import { MigrationService } from "@direct-democracy-solutions/elasticsearch-migration";
import type { IMigrationConfig } from "@direct-democracy-solutions/elasticsearch-migration";

const config: IMigrationConfig = {
  node: "http://127.0.0.1:9200",
  username: "elastic",
  password: "password",
  migrationsPath: "./migrations",
};

const migrationService = new MigrationService(config);

// Run all migrations
await migrationService.runMigrations();

// Check pending migrations
const pending = await migrationService.getPendingMigrations();
console.log(`Pending migrations: ${pending.length}`);

🧩 Migration Interface

interface IMigration {
  name: string;
  timestamp: number;
  up(client: Client): Promise<void>;
  down?(client: Client): Promise<void>;
}

⭐️ Features

  • ✅ TypeScript support
  • ✅ Elasticsearch/OpenSearch compatibility
  • ✅ Migration status tracking
  • ✅ Sequential migration execution
  • ✅ Rollback support
  • ✅ CLI interface
  • ✅ Programmatic API

🛠 Development

# Install dependencies
npm install

# Test (requires configuration -- see below)
npm test

# Run in development mode
npm run dev

# Build
npm run build

# Start (run built version)
npm start

# Migration commands (development)
npm run migrate -- create <name>   # Create new migration
npm run migrate -- up              # Run pending migrations
npm run migrate -- down            # Rollback last migration
npm run migrate -- forget          # Forget last migration, skip rollback
npm run migrate -- status          # Check migration status
npm run migrate -- list-indices    # List all indices
npm run migrate -- alias-info      # Show alias information

# Build and prepare for publish
npm run prepublishOnly

Test Configuration

The test suite needs a working Elasticsearch node to test against. To configure the test connection:

cp .env.example .env

And edit the values accordingly.

You can get a basic Elasticsearch instance using the Compose file:

docker-compose up -d

This setup will work with the values in .env.example, no edits needed.


License

MIT


About

A clean and extensible Elasticsearch migration framework for Node.js

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors