« Java 17 への移行(4) - OpenSearch の準備 [ubuntu 編] | トップページ | Java 17 への移行(6) - Hibernate 6 でやらかす »

2023年2月 2日 (木)

Java 17 への移行(5) - OpenDolphin server の対応

OpenSearch 関連設定

  • kuromoji を使用する JapaneseAnalysisConfigurer.java を作成する
    public class JapaneseAnalysisConfigurer implements ElasticsearchAnalysisConfigurer {
        @Override
        public void configure(ElasticsearchAnalysisConfigurationContext context) {
            context.analyzer("japanese").custom()
                .tokenizer("kuromoji_tokenizer")
                .charFilters("icu_normalizer", "kuromoji_iteration_mark")
                .tokenFilters("kuromoji_baseform", "kuromoji_part_of_speech", "ja_stop", "kuromoji_number", "kuromoji_stemmer");
        }
    }
    
  • ModuleModelBridge.java の代替手段
    masuda 先生の ModuleModelBridge.java をずっと使わせてもらっていたのであるが、アップデートで byte[] が byte と判定されるようになってしまい、動かなくなってしまった。そこで、シロウト丸出しな代替案として、fullText なる String フィールドをでっち上げて、setBeanBytes をフックして文字列を書き込ませて、それをインデックスさせるという手を使った。
    @Transient
    @FullTextField(analyzer = "japanese")  // hibernate search
    private String fullText;
    
    public void setBeanBytes(byte[] beanBytes) {
      this.beanBytes = beanBytes;
      // FullTextField を Index させるためのでっちあげ
      if (Objects.nonNull(beanBytes)) { setFullText(beanBytesToString(beanBytes)); }
    }
    
  • persistence.xml に JapaneseAnalysisConfigurer を認識させる
    <property name="hibernate.search.backend.type" value="elasticsearch"/>
    <property name="hibernate.search.backend.hosts" value="localhost:9200"/>
    <property name="hibernate.search.backend.protocol" value="http"/>
    <property name="hibernate.search.backend.analysis.configurer" value="class:open.dolphin.JapaneseAnalysisConfigurer" />
    

検索方法の種類

  • 新しい hibernate search では、検索方法も詳しく選べるようになっていて、通常の検索では phrase() サーチを採用し、simpleQueryString() サーチ、regexp() サーチもオプションできるようにプログラムした。

    List hits = searchSession.search(DocumentModel.class)
      .where(f -> f.bool(b -> {
        b.must(switch (spec.getType()) {
          case QUERY -> f.simpleQueryString().field("modules.fullText").matching(searchText);
          case REGEXP -> f.regexp().field("modules.fullText").matching(searchText);
          default -> f.phrase().field("modules.fullText").matching(searchText);
        });
        :
    

MassIndexer 関連

  • MassIndexer でインデックス条件を指定できるようになったので、STATUS_FINAL の DocumentModel だけインデックスするようにした。インデックス件数が 313,845件から 203,149件に減った。というか、今までは MassIndexer した分は、更新元の古いカルテも全部インデックスされてたということになる。

    MassIndexer massIndexer = searchSession.massIndexer();
    massIndexer.type(DocumentModel.class).reindexOnly("e.status = :status").param("status", IInfoModel.STATUS_FINAL);
    

    なお、ここの e.status ... の前のハードコードされてる sql が jpa compliance に反しているらしく exception を吐く。persistent.xml で hibernate.jpa.compliance.query = false の設定が必要。

MassIndexer のインデックススピードを比較してみたところ、現在使用中の i9-9900 の dolphin サーバで 14.5 doc/sec だったのに対して、こないだ購入した m1 max の mac studio では 41.3 doc/sec だった。例えば OpenSearch を強いマシンで動かして、それを dolphin サーバから利用するようにすると、インデックススピードの改善が期待できる。しないけど。

OpenDolphin サーバ起動

OpenSearch が立ち上がってから WildFly を立ち上げる必要がある。お前が使っているのは Elasticsearch じゃないぞと怒られるが気にしない。

  • OpenSearch が立ち上がった時のメッセージ

    [INFO ][o.o.c.m.MetadataCreateIndexService] [dolphin.local] [document-000001] creating index, cause [api], templates [], shards [1]/[1]
    
  • WildFly に怒られるところ

    WARN  [org.hibernate.search.backend.elasticsearch.dialect.impl.ElasticsearchDialectFactory] (MSC service thread 1-7) HSEARCH400085: Unknown Elast icsearch version running on the cluster: 'opensearch:2.4.1'. Hibernate Search may not work correctly. Consider updating to a newer version of Hibernate Search, if any.
    

ターミナルでの OpenSearch 動作確認

  • インデックス一覧
    $ curl 'http://localhost:9200/_aliases?pretty'
    {
      "document-000001" : {
        "aliases" : {
          "document-read" : {
            "is_write_index" : false
          },
          "document-write" : {
            "is_write_index" : true
          }
        }
      }
    }
    
  • アナライザの動作確認
    $ curl -X POST 'localhost:9200/document-000001/_analyze?pretty' -H "Content-type: application/json" -d '{"analyzer": "kuromoji", "text": "カルテ記載のテスト"}'
    {
      "tokens" : [
        {
          "token" : "カルテ",
          "start_offset" : 0,
          "end_offset" : 3,
          "type" : "word",
          "position" : 0
        },
        {
          "token" : "記載",
          "start_offset" : 3,
          "end_offset" : 5,
          "type" : "word",
          "position" : 1
        },
        {
          "token" : "テスト",
          "start_offset" : 6,
          "end_offset" : 9,
          "type" : "word",
          "position" : 3
        }
      ]
    }
    
  • 取得データ確認
    $ curl 'http://localhost:9200/document-000001/_search?pretty'
    
  • インデックス削除
    $ curl -X DELETE 'http://localhost:9200/document-000001?pretty'
    {
      "acknowledged" : true
    }
    

その他の WildFly 27 関連修正

  • javaee が jakartaee になっており、大量の javax を jakarta に書き換える必要があった。
  • RestEasy がバージョン 6 になって、RestEasyClient の作り方が変わった。
  • Hibernate Search 6 では、FullTextEntityManger ではなく、SearchSession で操作するようになった。
  • jackson はバージョン 2.13.4 になっており、jackson-databind が jackson.databind となる微妙な変化もあった。

« Java 17 への移行(4) - OpenSearch の準備 [ubuntu 編] | トップページ | Java 17 への移行(6) - Hibernate 6 でやらかす »

OpenDolphin」カテゴリの記事