Search Algolia index data with Golang client
このブログの記事検索にAlgoliaを使っています。
Algoliaはjsonでデータをクラウドにアップロードし、APIで検索したいキーワードを投げて結果を得ることの出来るサービスです。
AlgoliaはREST API以外にも一通り有名どころの言語のライブラリを提供しています。今回はGolangのライブラリを使用して、私のブログの記事を検索してjsonで結果を得るところまでやってみます。
準備としてとりあえずalgoliasearchをインストールしておきます。
go get github.com/algolia/algoliasearch-client-go/algoliasearch
簡単なことからやってみる
まずはQuick Startに従ってサンプルデータの検索をやってみます。
Quick Startではデータを登録する例から始まっていますが、今回はサンプルデータを手で直接Algoliaに登録しちゃいます。
contactsという名前でIndexを作成します。
早速登録したデータに対して検索を実行するコードを書いてみます。
search.go
- ドキュメントのままではエラーになるので(最低限の説明のみなので)多少コードが異なる
- アプリIDとAPIキーはAlgoliaの管理画面から確認できる
- 結果をfmt.Printlnで出力している
- APIキーとか公開されるの前提に使われる感じですが本能的に隠している...
- クイックスタートにならって
jimmie paint
で検索してみる
package main
import (
"fmt"
"github.com/algolia/algoliasearch-client-go/algoliasearch"
)
func main() {
client := algoliasearch.NewClient("アプリID", "APIキー")
index := client.InitIndex("contacts")
res, err := index.Search("jimmie paint", nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(res)
}
実行するとこんな結果になりました。
$ go run search.go
{ false map[] map[] [map[state:CA phone:209-525-7568 fax:209-525-4389 lastname:Barninger company:California Paint & Wlpaper Str city:Modesto county:Stanislaus address:Box #-4038 zip:95352 web:http://www.jimmiebarninger.com objectID:9446462 _highlightResult:map[zip:map[value:95352 matchLevel:none matchedWords:[]]phone:map[matchLevel:none matchedWords:[] value:209-525-7568] fax:map[value:209-525-4389 matchLevel:nonematchedWords:[]] email:map[value:<em>jimmie</em>@barninger.com matchLevel:partial fullyHighlighted:falsematchedWords:[jimmie]] company:map[fullyHighlighted:false matchedWords:[paint] value:California <em>Paint</em> & Wlpaper Str matchLevel:partial] address:map[value:Box #-4038 matchLevel:none matchedWords:[]] city:map[value:Modesto matchLevel:none matchedWords:[]] state:map[value:CA matchLevel:none matchedWords:[]]web:map[matchLevel:none matchedWords:[] value:http://www.jimmiebarninger.com] firstname:map[value:<em>Jimmie</em> matchLevel:partial fullyHighlighted:true matchedWords:[jimmie]] lastname:map[matchedWords:[] value:Barninger matchLevel:none] county:map[value:Stanislaus matchLevel:none matchedWords:[]]] firstname:Jimmie email:jimmie@barninger.com followers:3947]] 20 0 1 1 0 0 query=jimmie+paint 1 jimmie paint false false}
なんじゃこりゃ!
index.Search
の返り値を追ってみます。
index.Search
はQueryRes
を返し、QueryRes
は構造体のようです(インターフェース型?この辺あんま良くわかってない...)。
- algoliasearch-client-go/index.go at master · algolia/algoliasearch-client-go · GitHub
- algoliasearch-client-go/types_query.go at 82510b2fce0e1fa569cde912ca276b89185e87db · algolia/algoliasearch-client-go · GitHub
この構造体のフィールドに入る値の内容はQuick Start内に説明があります。どうやらHits
に検索して取得されたデータが入るようです。
このままでは見辛いので、jsonで出力するようにしてみます。Marshallすれば良さそう。ついでにインデントもつけてみる。
以下のようにコードを直します。
search.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/algolia/algoliasearch-client-go/algoliasearch"
)
func main() {
client := algoliasearch.NewClient("アプリID", "APIキー")
index := client.InitIndex("contacts")
res, err := index.Search("jimmie paint", nil)
if err != nil {
fmt.Println(err)
}
jsonBytes, err := json.Marshal(res)
if err != nil {
fmt.Println("JSON Marshal error:", err)
}
out := new(bytes.Buffer)
json.Indent(out, jsonBytes, "", " ")
fmt.Println(out.String())
}
実行してみる。
$ go run search.go
{
"hits": [
{
"_highlightResult": {
"address": {
"matchLevel": "none",
"matchedWords": [],
"value": "Box #-4038"
},
...
"hitsPerPage": 20,
"nbHits": 1,
"nbPages": 1,
"page": 0,
"params": "query=jimmie+paint",
"processingTimeMS": 1,
"query": "jimmie paint"
}
良さそう!
自分の記事データに対し検索する
やるにあたって、アプリID
、APIキー
、インデックス名
、検索ワード
をオプションで渡すようにしてみます。
実行してみます。
$ go run algoliasearch.go -d xxxxxxxx -k yyyyyyyy -i zzzzzzzz -q 'content security'
{
"hits": [
{
"_highlightResult": {
"created_at": {
"matchLevel": "none",
"matchedWords": [],
"value": "2017-02-03T10:51:30.000Z"
},
...
],
"hitsPerPage": 20,
"nbHits": 2,
"nbPages": 1,
"page": 0,
"params": "query=content+security",
"processingTimeMS": 2,
"query": "content security"
}
できた!
jqと組み合わせてみる
jqと組み合わせて、検索結果にヒットしたデータのタイトルデータのみ出してみます。
$ go run algoliasearch.go -d xxxxxxxx -k yyyyyyyy -i zzzzzzzz -q 'content security' | jq '.hits[].title'
"Trying out CSP(Content Security Policy)"
"What is do-agent by DigitalOcean"
Yay!
今後の予定
Alfredと組み合わせてみたい。
感想
- APIで全文検索できるの楽しい
- クイックスタートは本当に最低限のみの説明って感じなのでちょっと苦労した(Golang力なさ)
- ソースコード読んでようやくjsonで結果は帰ってこないことを理解した...
- 基礎力がないのでGolangチュートリアル繰り返したい