esaの従来の記事検索エンジン(v1)の様々な問題点を改善した、新しい記事検索エンジン(v2)を使えるようになりました。
なお、今後2ヶ月程度は従来の記事検索エンジン(V1)もお使いいただけます。この移行期間の間にv2で何か問題があった場合には、v1を使う設定に切り替えつつフィードバックをいただけると幸いです。
検索欄でクエリを入力すると、インクリメンタルサーチで上位数件の候補が表示され、それらを選択することでその記事を直接開くことが出来ます。また、そのキーワードで何件hitするのか確認できるので便利です。
以下のような要素に基づくスコアによって記事をソートします。
esaにログイン後に、記事一覧ページの「 検索エンジン切り替え」からv1とv2を切り替えることができます。
GET /v1/teams/:team/posts?q=foo&engine=v2
のように、クエリパラメータで engine=v2
を指定することができます。
また、
GET /v1/teams/:team/posts?q=foo&engine=v2&sort=stars&order=desc
のようにすることで、sortとorderを指定することができます。
sort
updated
(default)
created
stars
watches
comments
best_match
order
desc
(default)
asc
※ #196: ReleaseNotes/2016/10/22/UML記法に対応しました の機能を使いました ;)
従来の記事検索エンジン(v1)はesaの開発初期にPostgreSQLとactiverecord-hackery/ransackというgemで作った素朴なものでした。このアプローチではチームの記事数が増えていくにしたがって検索の速度や精度の悪化が顕著になり、スケールしません。
新しい記事検索エンジン(v2)のバックエンドには、Elastic CloudのTokyoリージョンのElasticsearch 5.0を使っています。Elasticsearchはスケーラブルな全文検索エンジンで、検索速度やREST-APIによる設定、柔軟なソート方法の指定なども魅力です。
gemに関してはankane/searchkickとelastic/elasticsearch-railsを検討してelasticsearch-railsを採用しました。両方でプロトタイプを作ってみた感想としては、自分でmappingを定義するようならelasticsearch-railsがいいと思います。searchkickはいろいろよしなにやってくれてお手軽なのですが、esaで使う場合にはparent/childなドキュメントに対応しない等の問題がありました。
ユーザーが入力した文字列をElasticsearchのクエリに変換する部分の開発には結構時間を使いました。開発初期は既存のライブラリやそれにパッチをあてたものを使っていましたが、esaの検索のためにカスタマイズする部分が多かったりと無理が出てきたので結局全部書き直しました。
早いもので、RubyKaigi後の9月中旬頃に新しい記事検索エンジンの実装に取り掛かってから約2ヶ月が経ってしまいました。その間Elasticsearchを再入門したり、体調がすぐれない時期があったり、会社が3期目に突入したり色々ありました。ともかく、この新しい記事検索エンジンをリリースできることを本当に嬉しく思います。
今回のリリースは「検索が遅い」「検索精度をもっと良くしてほしい」といった皆様からのフィードバックに背中を押してもらいました。これからも、ご不満やご要望やご感想のフィードバックをお待ちしております。そして今後も検索機能の他にも随時改善を続けていく所存ですので、よろしくお願いいたします。
[ProTip] Webhookでdocs.esa.ioの更新通知を受け取れるようになりました!
Enjoy "(\( ⁰⊖⁰)/)"
https://esa.io