【Solr】インデックス作成時に言語判定してフィールドを振り分ける

はじめに

Solrでインデックスしたいドキュメントが日本語だけと限らない場合があります。日本語の場合なら形態素解析ベースのトークナイザーを使いたいが、英語の場合は空白区切りベースのトークナイザーを使いたい。そういうときに使える言語判定の仕組みをSolrは備えています。

言語判定とスキーマ定義の方針

以下のような簡単なドキュメントを考えます。

[
    {
        "id" : "1",
        "text" : "Solr 8.4 からパッケージ管理機能が追加されました。リファレンスによると、ここでいうパッケージは1つまたは複数のプラグインを1つにまとめたものという意味のようです。Solr におけるパッケージ管理について調べました。",
    },
    {
        "id" : "2",
        "text" : "Starting in Solr 8.4, package management features have been added. According to the reference, package here means one or several plug-ins in one package. We looked at package management in Solr.",
    }
]

“text”が本文のフィールドで、ここに日本語の文章が入るかもしれないし、英語の文章が入るかもしれないという設定です。

日本語の場合は形態素解析を行う text_ja というフィールドタイプ、英語の場合は空白区切りベースの text_en というフィールドタイプにします。以下のようなスキーマ定義のイメージです。

<field name="text_ja"      type="text_ja"    indexed="true" stored="true"/>
<field name="text_en"      type="text_en"    indexed="true" stored="true"/>

言語判定の設定

以下を solrconfig.xml に追加して必要なライブラリを読み込みます。

<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-.*\.jar" />
<lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />

LangDetectLanguageIdentifierUpdateProcessor を使う updateRequestProcessorChain を設定します。

 <updateRequestProcessorChain name="langdet">
    <processor class="org.apache.solr.update.processor.LangDetectLanguageIdentifierUpdateProcessorFactory" name="langdet">
      <lst name="defaults">
        <str name="langid.fl">text</str>
        <str name="langid.langField">language</str>
        <str name="langid.whitelist">ja,en</str>
	<str name="langid.map">true</str>
        <str name="langid.fallback">other</str>
      </lst>
    </processor>
    <processor class="solr.LogUpdateProcessorFactory" />
    <processor class="solr.RunUpdateProcessorFactory" />
  </updateRequestProcessorChain>

上で設定した langdet チェインを update リクエストのときに使うように設定します。

  <initParams path="/update/**">
    <lst name="defaults">
      <str name="update.chain">langdet</str>
    </lst>
  </initParams>

langid パラメータの意味

langid.fl

言語判定処理の対象とするフィールド名。上の設定では text フィールドを対象としています。

langid.langField

言語判定結果の文字列(jaとかenなど)を格納するフィールド。上の設定では language フィールドを対象としています。

langid.whitelist

言語判定の対象とする言語名。上の設定では日本語と英語を対象としています。

langid.map

言語判定結果をフィールドにマッピングするかどうか。マッピングする場合はtrueを指定します。デフォルトでは {元のフィールド名}_{言語名} というフィールドにマッピングされます。上の設定では日本語判定の場合は text_ja フィールドに、英語判定の場合は text_en フィールドにマッピングされます。

langid.fallback

langid.whitelist で指定した言語にあてはまらない場合のマッピング先を決定するための文字列。上の設定では other を指定しているので、日本語でも英語でもない場合は text_other フィールドにマッピングされます。

スキーマ定義

言語判定の設定に基づいてフィールドを定義します。

<field name="text_ja"      type="text_ja"    indexed="true" stored="true"/>
<field name="text_en"      type="text_en"    indexed="true" stored="true"/>
<field name="text_other"      type="text_ngram"    indexed="true" stored="true"/>
<field name="language"  type="string"  indexed="true" stored="true"/>

updateリクエストで送られてきた text フィールドの内容を言語判定して、日本語なら形態素解析して text_ja フィールドに、英語なら StandardTokenizer を通して text_en フィールド に、それ以外なら ngram 分割して text_other フィールドに格納されます。

動作確認

上記の設定でコレクションを作成してサンプルドキュメントを投入してみます。

$ cd server/solr/configsets
$ cp -r _default langdet
[langdet/conf/{solrconfig.xml,managed-scheme}を編集
$ (cd langdet/conf && zip -r - *) |curl --user user:pass -X POST --header "Content-Type:application/octet-stream" --data-binary @- "http://localhost:8983/solr/admin/configs?action=UPLOAD&name=langdet"
$ curl --user user:pass 'http://localhost:8983/solr/admin/collections?action=CREATE&name=langdet&numShards=1&replicationFactor=1&collection.configName=langdet&wt=json'
$ cat ~/sample.json 
[
    {
        "id" : "1",
        "text" : "Solr 8.4 からパッケージ管理機能が追加されました。リファレンスによると、ここでいうパッケージは1つまたは複数のプラグインを1つにまとめたものという意味のようです。Solr におけるパッケージ管理について調べました。",
    },
    {
        "id" : "2",
        "text" : "Starting in Solr 8.4, package management features have been added. According to the reference, package here means one or several plug-ins in one package. We looked at package management in Solr.",
    }
]
$ bin/post -u user:pass -c langdet ~/sample.json

最近のSolrでは、認証を設定しないとsolrconfig.xml内にlibディレクティブでライブラリを追加できないので注意が必要です。

$ curl -s -u user:pass "http://localhost:8983/solr/wikipedia_langdet/select?omitHeader=true&q=*%3A*"
{
  "response":{"numFound":2,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"1",
        "language":"ja",
        "text_ja":"Solr 8.4 からパッケージ管理機能が追加されました。リファレンスによると、ここでいうパッケージは1つまたは複数のプラグインを1つにまとめたものという意味のようです。Solr におけるパッケージ管理について調べました。",
        "_version_":1682039285845327872},
      {
        "id":"2",
        "language":"en",
        "text_en":"Starting in Solr 8.4, package management features have been added. According to the reference, package here means one or several plug-ins in one package. We looked at package management in Solr.",
        "_version_":1682039286023585792}]
  }}

正しく言語判定されて、それぞれのフィールドに振り分けされました。

タコライスを作ってみたら、めっちゃカンタンで子供も喜んだ件

こんにちは。リモートワークで男子でも自炊が増えて、今まで作ったことのないレシピにも挑戦する方もいらっしゃるかなと思います。
どうせ作るなら子供に食べさせて喜ぶレシピがいいなと思っていて、チャレンジしてみたのがこちら。

美味しい☆タコライス
https://cookpad.com/recipe/1467554

食材は多少揃えないといけないですが、料理初心者の私でも作るのはとってもカンタンでサクッとできました!トマトやレタスの野菜がとれて、割とボリュームがあるのに子供もペロッと完食!これは定番入り間違いないです!!!

材料はこちら

↑の引用に近くはなりますが

レタス 葉っぱ1枚ぐらいで1人前。中の方なら2枚~3枚ぐらいでいけます。
トマト 1個(2人前)
合い挽きミンチ 200g(2人前)
玉ねぎ 半玉
ニンニク 一欠
とろけるチーズ 適量


調味料(タネのソース)

ケチャップ 大さじ2杯
ウスターソース 大さじ1杯
しょうゆ 大さじ1杯
料理酒 大さじ1杯
砂糖 小さじ1杯
オリーブオイル 大さじ2杯

作り方

(1)トマト準備
・トマトを1cm角ぐらいに斬る
 ※輪切りからの短冊切り×2
・ボールに入れて、ケチャップをまぶす
(2)タネのソース作り
・調味料を軽量カップなどにぶちこんでおく
(3)タネを作る
・ニンニクをみじん切りにする
・玉ねぎをみじん切りにする
・オリーブオイルを敷いて、↑のニンニク・玉ねぎを炒める
・多少かおりがしてきたら肉を投下&塩コショウ
・ソースをぶちかましておわり
(4)レタス準備
※ザルにレタスをむしって適当に洗いながら、手でちぎればOK!
(5)合体!
・器にお米を入れる
・レタスをのせる
・チーズをまぶす
・タネをのせる
・トマトをのせる
(6)おわり!
※タネは2人前なので注意。一人で食べるなら2回分なので残った分は皿に移せば次の日もタコライス食べれます。
※トマトも2人前ですが次の日の分に回すのが面倒くさいと思ったら全部たべてもOK!全部食べてもトマトが多すぎるって感じはそこまでしないです。

完成!

タコライス

初めてのトライで普通に美味しくできました。食材を揃えるのが面倒くさい部分はありますが、栄養・見た目・美味しさは抜群です!一度試してみてはいかがでしょうか!!マジでお勧めです!!

初心忘るべからず

本年もよろしくお願いいたします!
毎年ですが今年も一ヶ月が終わりかけている現実に驚愕しているマエダです。

コロナ禍ですので、社内メンバー集まっての書き初め発表はできませんでしたがSlack上でみんなの書き初め(ボールペンでも可)発表を実施しました。

昨年の書き初め記事はこちら。

今年の僕の書き初めはこちら。

年始に今年の一字を発表する会があり「生まれてはじめての2021年、初心を忘れず頑張ります!」的なことを発表したら「初」の字が一画足りていなくて「それはネ刀ですね」とその場にいた皆さんから総ツッコミをいただきました。

昨年も初心を忘れずにチャレンジすることを宣言しておりましたが「初心」の漢字を忘れておりましたので今年の書き初めはこちらにさせていただきました。
※ そもそも何回も書いてるので「書き初め」ではないというツッコミは受付終了いたしました。

昨年はいろいろと変化がありましたがまた新しい一年新しい気持ちで頑張ります!

いつもお世話になっている皆様、これからお世話になる皆様、スプラウトをよろしくお願いいたします!

<追記>
「初心忘るべからず」で検索すると深い意味があるようですので大変興味深いです。
要チェックや!

スタンディングデスクを一年使ってみての効果と感想

スタンディングデスクとは、イラストのような立ったままデスクワークが行える机のことです。
下記のような記事を見たりして、リモートワーク開始とともに試してみようと思いました。
(頭が良くなりたい 。。。)

スタンディングデスクを24週間使うと頭がグンと良くなるらしいぞ
https://yuchrszk.blogspot.com/2016/03/24.html

 

私の場合は、机の上にローテーブルをのせて、間に耐震マットを挟んで使っています。

スタンディングデスクのメリットは色々言われていて下記のようです。
■メリット
・集中力アップ
・眠気に襲われない
・活動的になれる
・消費カロリーが増える
・椅子がいらなくなる

 

デメリットとして下記があるようです。
■デメリット
・膝・腰に負担がかかる場合がある
・足の裏が痛い
・実はそんなにメリットがない?
https://www.cnn.co.jp/fringe/35126866.html

個人的には一年ほどやってみてありだと思いました。
(頭良くなっているかどうかは残念ながら不明ですが…)

 
最初の1ヶ月は足がパンパンになりましたが、それ以降は特に気になりません。

ただ自分の場合、右足に重心をかける癖があるのでそこが要注意で、
右膝を少し痛めたかなとか思ったりしています。
特に仕事中に、焦ってしまったときになるようです。

立ちっぱなし座りっぱなしどちらにしても同じ姿勢が、よくないようなので、昇降タイプのスタンディングデスクを近々買えたらと思っています。

(重たくて、大きくて、高価なので色々検討中です…)