この度は、「AI検索技術〜Solrエンジニアのための最先端ガイド〜」をお手に取っていただき、ありがとうございます。本書は、全文検索エンジンであるApache Solrのバージョン9から導入された密ベクトル検索機能について、その特徴と使い方を紹介する本です。
ベクトル検索は従来のキーワード検索では実現が困難だった、ニュアンスの検索や類似画像検索、レコメンド、テキストから画像や音声などメディアの垣根を越えたマルチモーダルな検索などなど、ユーザーにまったく新しい検索体験を提供できる可能性を秘めた検索手法です。その魅力の反面、Solr上でのベクトル検索は、全文検索エンジンの知識に加えて、機械学習分野の素養も求められます。そのため、導入の敷居が高いと感じられているチームが多いのではないでしょうか。
その証拠というべきか、Solrを使ったベクトル検索について、ビジネスでの実用実績はおろか、技術ブログすらほとんど見つからないという状況です。
そこで本書では、追加されたSolrの機能の使い方はもちろん、肝となるベクトル生成部分の実現例についてもご紹介します。これを読めば、検索チームが少なくとも機械学習チームとコミュニケーションを取ってベクトル検索を実現、あわよくば検索チーム単独でもベクトル検索を活用スタートできるようになることを目指した一冊です。
複数の分野の知見やノウハウが求められる分野であるため、網羅しきれていない部分があるかもしれません。私なりのノウハウを詰めましたので、みなさんのよきサービスやアプリ開発ライフの一助になれば幸いです。
本書に登場するサンプルコードは、GitHubにて公開しています1。必要に応じてご活用ください2。
本書に記載されている会社名、製品名などは、一般に各社の登録商標または商標、商品名です。会社名、製品名については、本文中では©、®、™マークなどは表示していません。
本書に記載された内容は、情報提供のみを目的としております。そのため、本書に記載された内容を用いた開発、制作、運用はご自身の責任と判断によって実施してください。利用の結果発生した事象に関しては、当方は一切の責任を負いかねます。
本書は、技術系同人誌即売会「技術書典14」で頒布された「今日から始めるSolrベクトル検索」を底本としております3。
はじめに、全文検索エンジンとSolrの概念や基礎知識について、お話ししておこうかと思います。本書を手に取っていただいた方の中には少ないと思いますが、Solrをはじめて触る、久しぶりすぎて何も覚えていないという方向けの章です。すべてを説明しきるには紙面が足らなさすぎるので、ベクトル検索やSolrのトラブルシュートに関係しそうなものを中心にピックアップしました。全文検索やSolrの基礎知識については理解できている、普段からSolrの運用をしているという方は、読み飛ばしてください。
みなさんは新しいことを知りたいとき、どうやってアプローチしますか?本を読む、人に聞く、インターネットで調べるなど、いろいろあるでしょう。
インターネットで調べる場合、GoogleやYahooなどの検索窓に、調べたいキーワードを入力するかと思います。たとえば、「沖縄の観光名所について調べたい」と思ったとします。検索窓に「沖縄 観光」や「沖縄 名所」「沖縄 旅行 おすすめ」などと入力して、検索ボタンを押します。すると、ブログやニュース記事、各社サイトのページ、論文など、インターネット上の膨大なドキュメントの「全文」すなわち「文章の始めから終わりまで」すべてがスキャンされます。その結果、「沖縄」や「観光」といった検索キーワードを含む記事や動画、画像などの情報を一度に探すことができます。このように、全文検索システムは、インターネット上の膨大な情報の中からほしい情報を見つけ出すための便利なツールです。
GoogleやYahooといった検索そのものを主軸にしたWebサービスはもちろん、多くのサイトにはこのような検索窓が付いています。ユーザーは検索窓に検索クエリを入力することで、そのサイト内のデータの中から所望の情報を見つけだすことができます。Web上に限らず、みなさんがお使いのテキストエディターやWord、Excel、メーラー、統合開発環境などにも検索機能はあることでしょう。
今ではごく当たり前にどこでもある機能、それが全文検索です。
全文検索の特徴は、検索したい情報の単語や文章の一部でも、その情報が含まれる文書を検索できることです。
たとえば、「沖縄の観光名所について調べたい」と思ったとします。全文検索を使えば、「沖縄」や「観光」が含まれる文章全体を検索できます。辞書を引くときのように、見出し語をドンピシャで当てる必要はありません。一度の検索で全文をスキャンし、適切な検索対象を探すことができるため、非常に便利です。また、検索結果はキーワードに周辺情報を含めた文章なので、より詳細な情報も手に入ります。
そんな便利で当たり前の機能である全文検索ですが、実用的に機能させるのは、決して容易ではありません。検索対象のデータの容量が大きいと、処理が遅くなるという課題があります。パソコン内のファイルシステムや、会社で使っている業務システムで検索しても、なかなか結果が返ってこない、エラー原因調査のために長大なログファイルを分析したいけど、検索以前にログの読み込みが遅すぎるという場面に、一度は遭遇したことがあるでしょう。検索対象が増えれば増えるほど、検索に時間がかかるようになるのは、想像に難くありません。しかも、文章全体をスキャンして検索キーワードにマッチする箇所がないかチェックするので、コストの大きい処理をさせていることは、直観的にも理解できるでしょう。
grepやfindなどで愚直に行うと、検索に非現実的な時間がかかることも珍しくありません。たとえインデックスを作って、SQLのLikeクエリで中間一致検索したとしても、解決できません。また、データベースはN+1問題と言われるように、高頻度でデータを取り出すことに不向きです。
時間だけでなく、膨大なドキュメント全体をスキャンするには、ある程度大きなサーバーリソースを消費します。そのため、負荷分散が必要になるといった課題もあります。
そこで生み出されたのが、全文検索に特化したシステムである、全文検索エンジンです。全文検索エンジンには、全文検索に適した検索の仕組みが備わっています。ですので、データベースでの検索に比べ、超高速に結果を得ることができます。
全文検索エンジンの多くは、インデックスを利用することで、大量の文書集合を高速に検索できます。
インデックスは、「どのドキュメントが、どの単語を含むのか」という情報を保存したテーブルです。ユーザーがクエリを発行した際、このインデックスを調べて、クエリ単語を含む文書集合を返します。全文書のコンテンツを愚直にgrepなどで走査する検索システムに比べ、インデックスを利用した検索システムの方が、高速に動作します。
また、インデックスであれば、検索対象となるドキュメント数が大きくなっても、検索性能はそれほど劣化しません1。そのため、大規模データを扱う高負荷な環境では、インデックスの利用がほぼ必須といえます。
インデックスのデータ構造には、いくつか種類があります。その中でも特にメジャーなのが、転置インデックス(Inverted Index)です23。
転置インデックスは、各単語と単語を含む文書IDからなるテーブルです。これに加えて、単語が文書の中で出現した位置情報を含む場合もあります。いわば、本の索引のようなものです。
たとえば、
・I have a bag.
・I play tennis.
・I eat rice.
という3文が検索対象だったとすると、次のような表を作ります。
I | have | a | bag | play | tennis | eat | rice | |
文 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
文 2 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
文 3 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
その文に含まれる単語は1、含まれなければ0になるような表です。この表は、結合行列と呼ばれています。
この結合行列から、どの文章にどの単語が含まれているかという索引を作ったのが、転置インデックスです。
Word | Doc ID |
I | 1,2,3 |
have | 1 |
a | 1 |
bag | 1 |
play | 2 |
tennis | 2 |
eat | 3 |
rice | 3 |
つまり、WordとDoc IDのKey-Valueデータです。
転置インデックスがあれば、検索が非常に簡単になります。たとえば、「tennis」というクエリに対しては、「tennis」をkeyにDoc ID 2をvalueとして返せば、ドキュメント全体を逐一スキャンすることなく、「tennis」を含む文章を見つけ出せます。
このように、あらかじめ転置インデックスを作成しておくことで、ある単語で検索したときに、その単語がどの文書に含まれているのかをすぐに探し出すことができます。インデックスの作成には時間を要しますが、いったん作ってしまえば、高速に検索できるのが利点です。
Apache Solr(以下、Solr)は、そんな全文検索エンジンのひとつです。
Solrでは、全文検索の課題克服のために作られた、全文検索エンジンライブラリーApache Luceneをベースにしています。Apache Luceneには、高速に膨大なデータを検索するためのアルゴリズムが実装されています。Solr以外にもElasticsearchなど、数多くの全文検索エンジンで使用されています。ちなみに、Apache LuceneもSolr自身もJavaで実装されています。
その始まりは、CNET Networks社によってSolarとして開発されました。その後、2006年1月にApacheコミュニティに寄贈され、Solrに改名されました。2007年1月からは、Apache Luceneのサブプロジェクトとなりました。以降、Apacheコミュニティによって開発が進められています。
SolrはOSSのため、無料で利用でき、商用利用も可能です4。OSSでありながら、商用の検索エンジンソフトを凌駕する豊富な機能を備えており、国内外問わず、多くの大規模サイトでSolrが使用されています。また、Solr自体はOSSですが、これを利用して、いくつかの製品ソフトウェアも開発されています。
Solrの特徴はいくつもありますが、代表的なものは以下です。
1.高速でスケーラブルな検索:スケールしやすいアーキテクチャのため、大量の文章であっても非常に高速な検索が可能
2.豊富な検索機能:キーワード検索をはじめ、ファセット検索、スペルチェック、近似検索、地理的検索、データフィルタリングなど、豊富な検索機能を搭載
3.拡張性:プラグインを組み込むことで、機能拡張やカスタマイズが容易に行える
4.多言語対応:Unicodeをサポートしており、日本語を含めさまざまな言語に対応できる
5.Webフレンドリーなインターフェイス:REST likeなAPIによってデータの追加、更新、削除、検索などが可能
6.分散処理:シャーディングやレプリケーションによって複数のSolrノードを組み合わせて、データの分散処理や高い可用性、耐障害性を実現できる
全文検索用の機能はもちろん、サービスとして運用するための機能も充実しています。