0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SpringData Elasticsearchでインデックスにエイリアスを貼る

Posted at

はじめに

SpringData Elasticsearch を利用していて、日毎にドキュメントの全件洗い替えを行いたかった。
その手段を考えた時に、エイリアス機能が使えないかと目星をつけ、実際に洗い替えが実現できたので作業ログを公開します。

概要

インデックスの洗い替えを考える。
現在日付を 01/11 とする時を想定。

  • A. Index-01/10 (バックアップ)
  • B. Index-01/11 (利用中)
  • C. Index-01/12 (今から作成する)

のように考える。
01/12 00:00 以降に定時バッチを起動する。

  1. C. Index-01/12 の名称でインデックスを生成する
  2. RDBからインデックスしたいレコードを検索する
    論理削除された情報は絞り込みで除外する
  3. C. にインデックスしたいドキュメント(2.の内容)を追加する

正常系:

  1. エイリアスに C. を追加する
  2. エイリアスから B. を削除する
  3. A. を物理削除する

異常系:

  1. エラーを出力する
  2. C. Index-01/12 を削除する

試した環境

ツール/ライブラリ バージョン
Elasticsearch 7.16.2
SpringData Elasticsearch 4.4.0-SNAPSHOT
SpringBoot 2.7.0-SNAPSHOT

実装

DTO

LocationDocument
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.elasticsearch.annotations.Document;

@TypeAlias("location")
@Document(indexName = "location-#{T(java.time.LocalDate).now().toString()}", createIndex = false)
public class LocationDocument extends BaseDocument<String> {

  public static final String ALIAS = "location";
  public static final String INDEX_NAME = "location-{yyyy-MM-dd}";

  @Id
  private String id;
}  

@TypeAlias のおかげで、 location という名前でアクセスできるインデックスが作成される。実態は location-2022-01-10 のような形式である。

エイリアス貼り替え

LocationRepositoryImpl
import lombok.RequiredArgsConstructor;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.index.AliasAction;
import org.springframework.data.elasticsearch.core.index.AliasActionParameters;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.stereotype.Repository;

@Repository
@RequiredArgsConstructor
public class LocationRepositoryImpl implements LocationRepository {

  private final LocationDocumentSource locationDocumentSource;
  private final LocationTableSource locationTableSource;
  private final ReactiveElasticsearchOperations elasticsearchOperations;

  @Override
  public void replacement(Instant receptionTime) {
    var today = LocalDate.now();
    var newIndexName = LocationDocument.INDEX_NAME
        .replace("{yyyy-MM-dd}", today.toString());
    var oldIndexName = LocationDocument.INDEX_NAME
        .replace("{yyyy-MM-dd}", today.minusDays(1L).toString());

    // index作成
    var indexOperations = this.elasticsearchOperations.indexOps(LocationDocument.class);

    indexOperations.create().block();

    // 直す
    var count = this.locationTableSource.findAll()
        .filter(BaseTable::isExists)
        .map(LocationTable::toEntity)
        .map(new LocationDocument()::attach)
        .flatMap(dto -> this.locationDocumentSource.insert(dto, receptionTime))
        .count()
        .block();

    indexOperations.alias(
        new AliasActions()
            .add(
                // Aliasに新しいindexを追加する
                new AliasAction.Add(
                    AliasActionParameters.builder()
                        .withIndices(newIndexName)
                        .withAliases(LocationDocument.ALIAS)
                        .build()
                )
            )
           .add(
               // Aliasから古いindexを削除する
               new AliasAction.Remove(
                   AliasActionParameters.builder()
                       .withIndices(oldIndexName)
                       .withAliases(LocationDocument.ALIAS)
                       .build()
               )
           )
        )
        .block();
  }

}

説明

  1. ReactiveElasticsearchOperations or ElasticsearchOperations をDIしておく
  2. AliasActions でエイリアスの操作を指定する
    エイリアスに C. を追加する
    エイリアスから B. を削除する
  3. ReactiveElasticsearchOperations or ElasticsearchOperations から ReactiveIndexOperations or IndexOperations を生成する
  4. ReactiveIndexOperations.alias() or IndexOperations.alias()AliasActions を指定する

日毎に洗い替えを行いたい場合、日付が変わった後にバッチなどで洗い替え処理を行えばよい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?