Apache Solr で異体字同時検索

さて、今回は異体字同時検索です。クラウドソーシング翻刻に限らず、字体・字形の選択ポリシーが一定していなかったり徹底されていなかったりということは、テキスト文字起こし全般においてしばしばみられます。普通にデータを作成していても、國學院大學を国学院大学と書いてしまったり、慶應義塾大学と慶応義塾大学が混在するという例は割と見られます。しかし、いちいち両方の単語を検索するのは大変ですし、Google検索や各地の検索システムでは、両方を同時に検索してくれることが結構多いように思われます。ではそれは特殊な技術かと言えばそんなことはなくて、たとえばApache Solrでは設定するだけでそれができるようになります。そこで、とりあえずその設定の仕方も含めて、一緒にやってみましょう。

ではまず、前回の手順をおさらいしつつ、今回の手順を確認してみましょう。

  1. Apache Solrをインストール&起動
  2. コアの作成
  3. 検索項目の設定(省略可)⇒今回はここを!
  4. 検索対象ドキュメントの登録

前回の手順では省略した、「3. 検索項目の設定」をきちんと設定するのが今回のポイントです。今回は、前回作ったminhonコアはそのままにしておきつつ、 新たに minhon2 というコアを作ることにして、以下、前回と重なるものは解説はざっくりするか飛ばしてコマンドのみ再掲します。

1. Apache Solrをインストール&起動

Apache Solrの最新版をダウンロードして圧縮ファイルを伸張し、そのディレクトリに入ってからPower ShellのターミナルかWSLターミナル、Macのターミナルなどを起動して、以下のようにしてSolrを起動。 Power Shellの場合は、

> bin/solr start

WSLターミナルの場合は(多分MacOSやLinuxでも同様に)

$ ./bin/solr start

※ startできないと言われたら、エラーメッセージにあわせて対応します。よくあるのはJAVAがない、あるいは、JAVA_HOMEがない、というエラーメッセージですが、JAVAをインストールしてない場合は、「無料Javaソフトウェアをダウンロード」からJAVA (runtime Environment)をダウンロード・インストールします。JAVA_HOMEがない、というエラーメッセージの場合は、JAVA_HOMEをウインドウズで設定します。JAVA_HOMEの設定は、ググると色々やりかたがでてきますのでそちらを参考にしてください。

2. コアの作成

Power Shellの場合は、

> bin/solr create -c minhon3

WSLターミナルの場合は(多分MacOSやLinuxでも同様に)

$ ./bin/solr create -c minhon3

3. 検索項目の設定(省略可)

ここまでは前回と一緒ですが、次が少々異なります。「3. 検索項目の設定(省略可)」を敢えて行います。

ここでの手順は、

3-1. フィールドタイプの設定 3-2. フィールドの設定

という風になります。つまり、「異体字検索用辞書を使って検索用インデックスを作るフィールドタイプ」というのを設定した上で、 「異体字検索用インデックスを検索したいフィールドに割り当てる」という手順になります。では以下でやってみましょう。

3-1. フィールドタイプの設定

「異体字検索用辞書を使って検索用インデックスを作るフィールドタイプ」を作成するのですが、このためには、まず、「異体字検索用辞書ファイル」を用意して、そのファイルパスを設定に組み込む必要があります。 そこで、まずは、空の「異体字検索用辞書ファイル」を作成しておきましょう。

Power Shellの場合

> mkdir server/solr/minhon3/dict > New-Item -Type File server/solr/minhon3/dict/itaiji.txt

WSL Ubuntu18やMac OS、Linux等の場合

$ mkdir server/solr/minhon3/dict $ touch server/solr/minhon3/dict/itaiji.txt

そうすると、以下のフォルダに、itaiji.txtというファイルができているはずです。(以下の画像は空のフォルダです)

f:id:digitalnagasaki:20200126180629p:plain
itaiji.txt

そこで、itaiji.txtを開いて、試しに以下の異体字ペアの内容を入力して、UTF-8で保存しておきましょう。記号も含めてこのまま入力してください。

"圖"=>"図"

"學"=>"学"

これで準備は終了です。

次に、この異体字検索用辞書ファイルを使って異体字同時検索のできるフィールドタイプを作成します。以下のようにコマンドをうってみましょう。

Power Shellの場合:

> curl.exe -X POST -H 'Content-type: application/json' --data-binary '{
    "add-field-type": {
        "name": "text_cjkuni",
        "class": "solr.TextField",
        "positionIncrementGap": 100,
        "analyzer": {
            "charFilters": [{
                    "class": "solr.MappingCharFilterFactory",
                    "mapping": "dict/itaiji.txt"
                }],
            "tokenizer": {"class": "solr.StandardTokenizerFactory"},
            "filters": [
                {"class": "solr.CJKWidthFilterFactory"},
                {"class": "solr.LowerCaseFilterFactory"},
                {
                    "class": "solr.CJKBigramFilterFactory",
                    "outputUnigrams": "true"
                }
            ]
        }
    }
}' http://localhost:8983/solr/minhon3/schema

WSL Ubuntu , Linux, MacOSなどの場合:

$ curl.exe -X POST -H 'Content-type: application/json' --data-binary '{
    "add-field-type": {
        "name": "text_cjkuni",
        "class": "solr.TextField",
        "positionIncrementGap": 100,
        "analyzer": {
            "charFilters": [{
                    "class": "solr.MappingCharFilterFactory",
                    "mapping": "dict/itaiji.txt"
                }],
            "tokenizer": {"class": "solr.StandardTokenizerFactory"},
            "filters": [
                {"class": "solr.CJKWidthFilterFactory"},
                {"class": "solr.LowerCaseFilterFactory"},
                {
                    "class": "solr.CJKBigramFilterFactory",
                    "outputUnigrams": "true"
                }
            ]
        }
    }
}' http://localhost:8983/solr/minhon3/schema

これで、フィールドタイプ text_cjkuni が作成されました。

3-2 フィールドの設定

次に、このフィールドタイプが適用されるフィールドを設定します。これまで作ってきたドキュメント登録用ファイルの中の textConn というフィールドに、これを割り当ててみます。以下のコマンドを打ってみましょう。

Power Shellの場合:

> curl.exe -X POST -H 'Content-type: application/json' --data-binary '{
"add-field" : {
"name":"textConn",
"type":"text_cjkuni",
"indexed":"true",
"stored":"true",
"required":"false",
"multiValued":"false" }}' http://localhost:8983/solr/minhon3/schema

WSL Ubuntu , Linux, MacOSなどの場合:

$ curl -X POST -H 'Content-type: application/json' --data-binary '{
"add-field" : {
"name":"textConn",
"type":"text_cjkuni",
"indexed":"true",
"stored":"true",
"required":"false",
"multiValued":"false" }}' http://localhost:8983/solr/minhon3/schema

これで、textConnフィールドに対しては、異体字同時検索がかかるようになります。

4. 検索対象ドキュメントの登録

今回は、minhon3.jsonという登録用ドキュメントをまとめたファイルを新たに作ってみました。

https://vayu.dhii.jp/minhon_search/minhon3.json

これは、テキストの内容は同じですが、id というフィールドを新たに追加しています。このidフィールドを登録ドキュメントに設定しておくと、 検索インデックスの上書き更新が可能になりますので後々便利です。

それでは、minhon3.jsonをダウンロードして、それが置いてあるフォルダでターミナルを開いて(あるいは、現在ターミナルで開いているフォルダにminhon3.jsonを持ってきて(お勧め!))、 以下のようにして、検索対象ドキュメントの入ったminhon3.jsonを、新しく作ったコア minhon3に登録してみましょう。

Power Shellの場合

> curl.exe "http://localhost:8983/solr/minhon3/update?commit=true" --data-binary "@minhon3.json" -H 'Content-type:text/json;charset=utf-8'

WSL Ubuntu18やLinux、MacOS等の場合

$ curl "http://localhost:8983/solr/minhon3/update?commit=true" --data-binary "@minhon3.json" -H 'Content-type:text/json;charset=utf-8'

これで、フィールド「textConn」は、上記の二つの異体字の対応づけが行われた状態の検索インデックスが作成されました。

さて、どうなったか確認してみましょう。

異体字同時検索の設定をしたtextConnで「"東京大學圖書"」を検索すると、以下のように"numFound":31、つまり、31件のドキュメントがヒットしています。「"東京大学図書"」でも同様です。(二重引用符で囲むのを忘れないようにしてください!)

f:id:digitalnagasaki:20200126174308p:plain
marge_result

一方、同じデータだが異体字同時検索の設定をしていないフィールド、textNoKTで検索すると(「df」項目に「textNoKT」と入力して検索)、以下のように、"東京大学図書"では23件、"東京大學圖書"では8件となります。あわせて31件ですから、ちょうどぴったりですね。

f:id:digitalnagasaki:20200126174849p:plain
noitaiji2

f:id:digitalnagasaki:20200126174654p:plain
noitaiji1

これが異体字同時検索の基本的なやり方です。

異体字のペアを後から追加する場合:

異体字のペアを増やしたければ、上記のitaiji.txtにペアを追加していけばいいのですが、こちらは複数文字でも対応してくれるようで、たとえば以下のものなどもできるようです。

"圕"=>"図書館"

ただし、ペアを増やしたら、Apache Solrを再起動してあげなければなりません。再起動は、以下のコマンドで行います。

> bin/solr restart -p 8983

(WSLとかMacでも一緒です)

そして、再起動しただけだと、矢印方向の変換しか効きません。これだと逆方向が検索できなくなってしまうので、「検索インデックスへの再登録」も行う必要があるようです。 ここで、先ほどの、「idを付与」した minhon3.json が活きてきます。再登録は、登録時と同じコマンドで大丈夫です。(もっと効率の良い方法があるかもしれませんが)

Power shellの場合は:

> curl.exe "http://localhost:8983/solr/minhon3/update?commit=true" --data-binary "@minhon3.json" -H 'Content-type:text/json;charset=utf-8'

WSL Ubuntu やLinux、MacOSなどの場合は: $ curl "http://localhost:8983/solr/minhon3/update?commit=true" --data-binary "@minhon3.json" -H 'Content-type:text/json;charset=utf-8'

これで大丈夫かと思います。

複数文字対応ができるということは、単語・フレーズ単位での表記揺れのようなことにも対応できますし、さらに言えば、たとえば、"安震"=>"安政大地震"と登録すれば、「安震」で「安政大地震」を検索するようなこともできるようになります。

ということで、Apache Solrの異体字同時検索、ぜひお試ししてみてください。