現在JavaScriptの設定が無効になっています。このページを利用するにはJavaScriptの設定を有効にしてください。トップ全記事一覧テクノロジー2018.03.09インターンシップ生がVespaを使って検索システムを作ってみた話はじめにこんにちは、インターンシップ生の室岡です。今回は、私がインターンシップで作った「郵便番号検索システム」について紹介させていただきます。Vespaとは今回の郵便番号検索システムを作るにあたって、検索エンジンはVespaを使いました。JAPAN内の多くの検索システムでVespaが採用されています。Vespaは2017年9月にOSSとして公開されました。Vespaには数多くの機能があり本家ドキュメントが充実しており、その機能のうちのいくつかを紹介します。リアルタイム大規模なデータを数msで検索できます。ランキング多様なマッチングロジックが実装されており、ランキング方法を自分で柔軟にカスタマイズできます。テンソルフレームワークベクトル、行列演算などの基本的な数学的演算を使うことができます。これにより学習済みモデルを用いて分類や回帰ができます。GitHubのリポジトリはこちらです。Vespaの動かし方チュートリアルの通りに実施すれば簡単な検索システムを試すことができました。やることをまとめるとVespaをセットアップVespaを使うサンプルプログラムをGitからダウンロードVespaのConfigServerを起動ダウンロードしたサンプルプログラムをVespaサーバーにデプロイVespa本体の起動Vespaに検索データをフィードVespaに対して検索を実施これでVespaの動かし方が分かりました。これから実際に郵便番号検索システムにカスタマイズしていきます。郵便番号検索インデックスの構造を定義Vespaの動作には、検索インデックスの定義、システム構成、サービスの詳細設定といった設定が必要なため変更を行っていきます。基本的に1つのデータに関して1つのfieldが対応します。以下のコードでは表示用と検索用の郵便番号や住所に加え、それらを数値化したデータを持っています。数値化したデータは後に紹介するソートで使います。今回は検索に使用するノードが1ノードのみなのでチュートリアル通りの設定を利用しました。</host></hosts>サービスの詳細設定Vespaをサーバーとして稼働させるために必要な設定です。チュートリアルの設定をインデックス定義にあわせて変更しております。</content></services>上記の編集が終わったらこの設定をVespaにデプロイします。全国の郵便番号を郵便局からダウンロードします。ダウンロードした書式はCSVファイルなのでVespaが対応しているJSONファイルに変換する必要があります。今回はPythonを用いてこの処理をしました。CSVファイルを入力としてJSONファイルを出力するPythonのソースコードは以下です。先ほど作ったJSONファイルをサーバー上に配置します。scpコマンドなどを使ってできます。次にJSONファイルを展開します。以下のコマンドでpostal-code.jsonをVespa仕様に展開できます。8080検索の実行Vespaの設定が終わったのでVespaで正しく検索できるか確認してみます。一般的な検索例サーバー上で以下のコマンドを入力することで検索できます。検索内容(query)と表示件数(count)を指定して検索しています。検索結果のレスポンスをXMLに変更することもできます。</hit></result>ソート検索結果の表示順を名前順で昇順や降順で並べ替えたい時にこの機能を使います。郵便番号や住所を名前順になるように数値化(文字コードに変換)しておき、それを検索インデックスとして登録することでソートを可能にします。</hit></result>ランキング検索結果の表示順をより高度に制御するためにランキング式を定義できます。ランキング式を定義しなかった場合、「岡山」というワードで検索すると以下のように大阪府のヒットした住所が一番上に出てきてしまいます。}}通常は「岡山」と検索した場合は岡山県が一番上に出てくることを期待することが多いのでランキングの機能を使います。今回はこの機能を実現するためにaddress.sd中のrank-profile中でランキング方法の定義をしています。}}通常ランキングは複数の段階に分けます。最初は大ざっぱなランキングをしてから次に細部のランキングをすることで計算時間を短くできます。first-phaseが最初のランキングでデフォルトの大ざっぱなランキングであるnativeRankを使っています。fieldMatch(house_number)の数式に従いランキングをしています。簡単に説明すると、これはprefecture、city、house_numberが検索に引っかかっているかどうかに関して重みづけをしてその線形和を点数とし、その点数が高い順にランキングします。このランキングを設定して再びデプロイしたのち「岡山」で検索をかけると、以下のように岡山県のみがヒットしていることがわかります。}}Searchについて詳しくはこちらをご覧ください。検索クエリは、ユーザーが実際に入力する文字列のため、表記のユレが存在します。「1028282」という郵便番号を検索する場合、「102-8282」や「〒1028282」で検索をかけるユーザーもいるかもしれません。その場合でも検索を可能にするため、「-」や「〒」などの余分な文字があった場合にそれらを排除した方が良いかもしれません。componentsで処理を挿入することができます。今回の要件を実装してみたコードは以下の通りです。"常識ですがさいたま市はひらがなで書きます。}}そして依存関係を注入するためにservices.xmlに追記を行います。</content></services>上記の編集が終わったらこの設定をVespaにデプロイします。activateこうすることで任意のAPIなどを用意することなく検索に関する処理を追加できるのもVespaのユニークな特徴かもしれません。詳細はこちらをご覧ください。5丁目」のような「丁目」や「番地」のワードが入っている住所の検索は対応できませんでした。郵便局からダウンロードした郵便番号CSVファイルが以下のような書式になっており、「丁目」や「番地」をうまくJSONファイルに書き下すのが困難だったからです。2~5番地)","北海道","旭川市","東旭川町東桜岡(30~499番地)","北海道","石狩市","八幡町(その他)","北海道","山越郡長万部町","静狩(3~1番地)","北海道","奥尻郡奥尻町","湯浜(神威脇、幌内)","北海道","久遠郡せたな町","瀬棚区本町(4区)","北海道","虻田郡京極町","以下に掲載がない場合",また、郵便番号CSVファイルの仕様として以下のように住所が長い場合は複数行にまたいで書かれています。この住所も今の実装だと検索することはできません。千葉県","旭市","琴田(85~160、1386~1815、2\\593~2820、","千葉県","旭市","3598~3614番地)",これらのユースケースに対応することが今後の課題です。おわりに今回、Vespaを用いて郵便番号検索システムを作りました。インターンの期間が一週間と短かったですが、Vespaの特徴や使い方を学ぶことができました。その他、サーバーサイド側や機械学習を使って開発をしているエンジニアの方達とお話をする機会をいただきとてもためになる一週間でした。Vespaはとてもレスポンスが速く追加機能も豊富な検索エンジンです。手軽に試せるのでみなさんぜひ一度Vespaを使ってみてはいかがでしょうか。MEETUPでVespaの開発者の話を聞くことができます。N-gramについてもチャレンジできると良いかもしれませんね。匿名希望のメンターMより。JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。JAPANのサービス開発を支える技術やデザイン、文化を発信しています。Reserved.このページの先頭へ。