「マンガ読んだ!!」のAzure Searchを使ったテキスト検索について

この内容は Azure Advent Calendar 2019 - Qiitaの22日目の記事です。僕はマンガ読んだ!!いうサービスを1人で2年半以上作っています。マンガ読んだ!!は、自分が読んだマンガのログを残すことが出来るマンガログサービスです。

マンガ読んだの検索テキストボックス

マンガ読んだ!!ではデータベースにSQL Serverを使っています。さて、マンガ読んだには検索用のテキストボックスがあります。普通、検索テキストボックスは全文一致を採用していると思います。つまり「こちら」と打っても、「葛飾区」と打っても、「派出所」と打っても、「こちら葛飾区亀有公園前派出所」がヒットします。クエリ的に言うと、Title like N'%*%' です。そして全文検索はとても遅いです。実際マンガ読んだ!!での検索テキストボックスの検索は作った当初遅すぎました。

マンガ読んだの検索テキストボックスの検索が遅かった理由

いくつか原因が重なってなんと30秒近くかかっていました。最初は完全一致で作っていて、ある時全文一致に変えたので、気づいていなかったのもあります。完全一致なら5秒ぐらいでした。ただ、その他にもBlazorの技術的な理解不足により検索が2回以上走っていたことやクエリ自体の書き方にも遅くなる問題がありました。しかし、それらを解消してもまだ使えないぐらいの遅さでした。一番は単純に全文一致が遅いんです。

Azure Searchの高速性

当初知識がなかったですが、全文検索はやはり何かしら別のアプローチをするのが常套手段のようでした。その時調べていて候補に挙がったのがAzure Searchでした。Azureのサービスの中に解決法があるとは思ってなかったので、これを見つけた時は、お、使っているサービスで賄いきれるのかとちょっと嬉しくなりました。で、使ってみました。Azure SearchはSQL Serverを元にインデックスを作る機能もあるので、あまり何もみずポータル上でポチポチやっているだけでもわりと使えました。そしてポータル上で全文検索出来たので使ってみると…、え!一瞬じゃん。。1秒以内にレスポンスがあって、本当に驚きでした。Azure Searchを使う意味はもうここがほぼ全てと言っても過言ではありません。トニカク速い!

Azure Searchヒットの謎

さて超高速で使える全文検索ですが、ヒットする内容を詳しく見ていると多少の謎があります。例えばHUNTER×HUNTER 1で検索した場合、HUNTER×HUNTER 1が最も高得点にヒットします。これは分かりやすい。ただ2番目以降のスコアは良くわかりません。特に?と思ったのが「CITY HUNTER」が「HUNTER HUNTER総集編」より高いスコアでヒットしたりしました。また、点数が低いとなんでこの内容がヒットした?と思えるものもあります。あいまい検索でのヒットも同様で、どの曖昧語でヒットするかが良くわかりません。HANTERはヒットしませんでした。ただ、ここを突きつけめても結局UI/UXの向上には殆ど繋がらないと思ったので特に掘っていません。

Azure Searchプログラムインデックス

さて、ポータルポチポチで作れても、ちゃんと使っていくにはプログラムでの操作も必要です。最初にインデックスの更新です。一応Azure Searchに自動同期機能もあります。スケジュール設定で例えば1日1回同期させておけばSQL Serverが変更していても連動します。これでよければやる必要はありません。ただ、やはりSQL Serverへ追加すると「同時」にAzure Searchも更新したくなります。そうなってくるとプログラムで更新してやる必要があります。SQL Serverのテーブルと同じclassを使いまわしてやればすむ…と思ったのですが、出来ない。何故だ何故だと思ったら罠がありました。SQL ServerのテーブルのIDはint、Azure SearchのテーブルはIDがstringです。なんで、stringにした??

Azure Searchプログラム検索

次にプログラムで検索しようとすると、クエリ構文がちょっと面食らいました。特に比較演算子記号(=,<,>)じゃないので都度調べるのが面倒です。普通のクエリにしてくれれば良いのにとは思います。検索がプログラムで出来るようになって、フィルターやソートに対応出来れば検索としてはほぼ全て出来ると思います。

インクリメンタルサーチ

あとわりと大事な機能にインクリメンタルサーチがあります。Azure Searchはこちらにも対応していて結果を返してくれます。インクリメンタルサーチhtml5のdatalist タグを使うとかなり楽に実装出来ます。ところがdatalist タグ自体にも問題が結構あるみたいで、特に全角英語が混じっていると上手く出ないことがあったりします。でも100%じゃなくて良くわからないです。あとAzure Searchが出す一覧も同じように謎があります。でも、まあそれらの問題がありつつも、使えなくもないレベルで使えます。逆にその手の問題がコントロール出来ても抜群に使いやすくなるとも思えず、スルーしてます。

まとめ

Azure Searchは兎に角速いのでこれだけで使う意味があります。いくつか分からないこともありますが、分からないなりに使ってもそれなりに使えます!