アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

検索のキホンのキ!

こんにちは!!こんにちは!!
検索技術勉強会に参加する程度には検索に詳しいmoriyamaです。

最近チーム内でSolrCloudの簡単な操作方法をレクチャーしました。
ZooKeeperとSolrの起動方法や、SolrCloudステータス確認といった、基礎的な運用だけなんですけどね。

改めて考えると、検索の仕組みをチーム内に共有していなかったので、
それも兼ねて今回はざっくり解説していこうと思います!


そもそも『検索』とは?

Wikipedia先生によると、下記のように書かれています。

検索とは、データの集合の中から目的のデータを探し出すことである

データの集合(=インデックス)から条件(=クエリ)を指定して、目的のデータを探し出すわけですね!

簡単なテキストデータであればUNIXコマンドのgrepで良いのですが、
ファイルの先頭から順次走査して条件比較するため、検索対象のファイルが多くなるほど検索速度は低下します。

そこで検索エンジンは『転置インデックス』を使って、探索の高速化を実現しています。


転置インデックスの仕組み

下記のようなドキュメントがあったとします。

ID テキスト
1 カツオはサザエの弟
2 サザエはワカメの姉
3 ワカメはカツオの妹

一般的なリレーショナルデータベースは、IDをベースにインデックスを構築すると思います。
転置インデックスは名の通り『転置』するので、下記のように単語やワードをベースにインデックス構築します。

ワード ドキュメントID
サザエ 1, 2
カツオ 1, 3
ワカメ 2, 3
1
2
3

こうすることで、各ワードで元のドキュメントにリレーションを張ることができました。

それでは下記のような検索クエリを実行したとしましょう。

ワカメAND

ワカメ { 2, 3 } が、 { 2 } がそれぞれ取得でき、
ANDクエリなので積集合をとると、 { 2 } になるので 「サザエはワカメの姉」 が検索できます。


辞書の使い方

一般論として、検索エンジンにインデックスする際は形態素解析でトークン化(トークナイズ)された単語・ワードを活用すると思いますが、
仮名や略語といった応用的な場面で検索するには少し手を加えてやる必要があります。

その第一歩として、『辞書』の活用が容易ですね。
例として、「いこーよ」というワードで考えてみましょう。

●ユーザー辞書

何も考えずにmecabで形態素解析を実施すると、下記のようになります。

$ echo いこーよ | mecab  
いこ 動詞,自立,*,*,五段・カ行促音便,未然ウ接続,いく,イコ,イコ  
ー  名詞,一般,*,*,*,*,*  
よ  助詞,終助詞,*,*,*,*,よ,ヨ,ヨ  
EOS

つまり、「いこ」「ー」「よ」という単語に分かれてしまうわけですね!
以前も記事にしたのですが、固有名詞は意図しないトークンに分割されやすいです。
それを防ぐため、分割されて困る単語はユーザー辞書に登録しましょう!

●同義語(シノニム)辞書

厳密には意味が異なるけれども、と同じ意味で検索させたい場合もありますよね?
例えば「いこレポ」「いこーよ」で検索した際にhitさせたいという需要はあると思います(あるよね?
そこで使うのが同義語辞書です。

(検索エンジンにも依りますが)同義語は双方向、片方向など、単語単語で細かい設定ができます。


まとめ

『転置インデックス』と『辞書』を押さえておけば、まず問題ありません!
検索にhitする/しないの原因はほとんどの場合、上記の2点を確認すれば解決するパターンが多いです。
※ あくまで個人の見解です

更に理解を深めるとしたら、『重み付け』や『再現率』『適合率』など終わりが見えませんね!
検索はとても奥が深いですし、自分もまだまだ勉強していきたいです。


さいごに

アクトインディでは一緒にサービスを育てたいエンジニアを募集しています!

actindi.net