Droonga を使った検索システムを自分で構築できるようになる。
分散データ処理エンジンです。 “distributed-groonga” に由来します。
Droonga は複数のコンポーネントから構成されています。ユーザは、これらのパッケージを組み合わせて利用することで、全文検索をはじめとするスケーラブルな分散データ処理システムを構築することができます。
Droonga Engine は Droonga における分散データ処理の要となるコンポーネントです。リクエストに基いて実際のデータ処理を行います。
このコンポーネントはdroonga-engineという名前で開発およびリリースされています。 通信に使用するプロトコルはFluentdと互換性があります。
droonga-engine は検索エンジンとして、オープンソースのカラムストア機能付き全文検索エンジン Groonga を使用しています。
Protocol Adapter は、Droonga を様々なプロトコルで利用できるようにするためのコンポーネントです。
Droonga Engine自体は通信プロトコルとしてfluentdプロトコルにのみ対応しています。 その代わりに、Protocol AdapterがDroonga Engineとクライアントの間に立って、fluentdプロトコルと他の一般的なプロトコル(HTTP、Socket.IOなど)とを翻訳することになります。
現在の所、HTTP用の実装として、Node.js用モジュールパッケージのdroonga-http-serverが存在しています。 言い直すと、droonga-http-serverはDroonga Protocol Adapterの一実装で、言わば「Droonga HTTP Protocol Adapter」であるという事です。
チュートリアルでは、以下の様な構成のシステムを構築します。
+-------------+ +------------------+ +----------------+
| Web Browser | <--------> | Protocol Adapter | <-------> | Droonga Engine |
+-------------+ HTTP +------------------+ Fluent +----------------+
w/droonga-http protocol w/droonga-engine
-server
\--------------------------------------------------/
この部分を構築します
ユーザは Protocol Adapter に、Web ブラウザなどを用いて接続します。Protocol Adapter は Droonga Engine へリクエストを送信します。実際の検索処理は Droonga Engine が行います。検索結果は、Droonga Engine から Protocol Adapter に渡され、最終的にユーザに返ります。
例として、ニューヨークにあるスターバックスの店舗を検索できるデータベースシステムを作成することにします。
まずコンピュータを調達しましょう。このチュートリアルでは、既存のコンピュータにDroongaによる検索システムを構築する手順を解説します。
以降の説明は基本的に、DigitalOceanで Ubuntu 13.10 x64
の仮想マシンのセットアップを完了し、コンソールにアクセスできる状態になった後を前提として進めます。
注意:Droongaが必要とするパッケージをインストールする前に、マシンが2GB以上のメモリを備えていることを確認して下さい。メモリが不足していると、ビルド時にエラーが出て、ビルドに失敗することがあります。
ホストが 192.168.0.10
だと仮定します。
Droonga をセットアップするために必要になるパッケージをインストールします。
# apt-get update
# apt-get -y upgrade
# apt-get install -y ruby ruby-dev build-essential nodejs npm
Droonga Engine は、データベースを保持し、実際の検索を担当する部分です。 このセクションでは、 droonga-engine をインストールし、検索対象となるデータを準備します。
# gem install droonga-engine droonga-client
Droonga Engine を構築するのに必要なパッケージがセットアップできました。引き続き設定に移ります。
まず Droonga Engine 用のディレクトリを作成します。
# mkdir engine
# cd engine
以下の内容で catalog.json
を作成します。
catalog.json:
{
"version": 2,
"effectiveDate": "2013-09-01T00:00:00Z",
"datasets": {
"Starbucks": {
"nWorkers": 4,
"plugins": ["groonga", "crud", "search"],
"schema": {
"Store": {
"type": "Hash",
"keyType": "ShortText",
"columns": {
"location": {
"type": "Scalar",
"valueType": "WGS84GeoPoint"
}
}
},
"Location": {
"type": "PatriciaTrie",
"keyType": "WGS84GeoPoint",
"columns": {
"store": {
"type": "Index",
"valueType": "Store",
"indexOptions": {
"sources": ["location"]
}
}
}
},
"Term": {
"type": "PatriciaTrie",
"keyType": "ShortText",
"normalizer": "NormalizerAuto",
"tokenizer": "TokenBigram",
"columns": {
"stores__key": {
"type": "Index",
"valueType": "Store",
"indexOptions": {
"position": true,
"sources": ["_key"]
}
}
}
}
},
"replicas": [
{
"dimension": "_key",
"slicer": "hash",
"slices": [
{
"volume": {
"address": "192.168.0.10:10031/droonga.000"
}
},
{
"volume": {
"address": "192.168.0.10:10031/droonga.001"
}
},
{
"volume": {
"address": "192.168.0.10:10031/droonga.002"
}
}
]
},
{
"dimension": "_key",
"slicer": "hash",
"slices": [
{
"volume": {
"address": "192.168.0.10:10031/droonga.010"
}
},
{
"volume": {
"address": "192.168.0.10:10031/droonga.011"
}
},
{
"volume": {
"address": "192.168.0.10:10031/droonga.012"
}
}
]
}
]
}
}
}
このcatalog.json
では、データセットStarbucks
を以下のように定義しています:
これらの6つの、"address"
の情報を持つ最小単位のボリュームは、内部的にシングル・ボリュームと呼ばれます。
"address"
の情報は、対応する物理的なストレージであるGroongaのデータベースの位置を示していて、それらのデータベースはdroonga-engine
によって自動的に作成されます。
catalog.json
の詳細については catalog.json を参照してください。
以下のようにして droonga-engine を起動します。
# droonga-engine --host 192.168.0.10 --log-file=$PWD/droonga-engine.log --daemon --pid-file $PWD/droonga-engine.pid
最初にdroonga-engineを終了する方法を知っておきましょう。
droonga-engineにSIGTERMを送ります。
# kill $(cat droonga-engine.pid)
これがdroonga-engineを終了する方法です。
再度droonga-engineを起動します。
# droonga-engine --host 192.168.0.10 --log-file=$PWD/droonga-engine.log --daemon --pid-file $PWD/droonga-engine.pid
Dronga Engine が起動したので、データを投入しましょう。
店舗のデータ stores.jsons
を用意します。
stores.jsons:
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "1st Avenue & 75th St. - New York NY (W)",
"values": {
"location": "40.770262,-73.954798"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "76th & Second - New York NY (W)",
"values": {
"location": "40.771056,-73.956757"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "2nd Ave. & 9th Street - New York NY",
"values": {
"location": "40.729445,-73.987471"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "15th & Third - New York NY (W)",
"values": {
"location": "40.733946,-73.9867"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "41st and Broadway - New York NY (W)",
"values": {
"location": "40.755111,-73.986225"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "84th & Third Ave - New York NY (W)",
"values": {
"location": "40.777485,-73.954979"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "150 E. 42nd Street - New York NY (W)",
"values": {
"location": "40.750784,-73.975582"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "West 43rd and Broadway - New York NY (W)",
"values": {
"location": "40.756197,-73.985624"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Macy's 35th Street Balcony - New York NY",
"values": {
"location": "40.750703,-73.989787"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Macy's 6th Floor - Herald Square - New York NY (W)",
"values": {
"location": "40.750703,-73.989787"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Herald Square- Macy's - New York NY",
"values": {
"location": "40.750703,-73.989787"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Macy's 5th Floor - Herald Square - New York NY (W)",
"values": {
"location": "40.750703,-73.989787"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "80th & York - New York NY (W)",
"values": {
"location": "40.772204,-73.949862"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Columbus @ 67th - New York NY (W)",
"values": {
"location": "40.774009,-73.981472"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "45th & Broadway - New York NY (W)",
"values": {
"location": "40.75766,-73.985719"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Marriott Marquis - Lobby - New York NY",
"values": {
"location": "40.759123,-73.984927"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Second @ 81st - New York NY (W)",
"values": {
"location": "40.77466,-73.954447"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "52nd & Seventh - New York NY (W)",
"values": {
"location": "40.761829,-73.981141"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "1585 Broadway (47th) - New York NY (W)",
"values": {
"location": "40.759806,-73.985066"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "85th & First - New York NY (W)",
"values": {
"location": "40.776101,-73.949971"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "92nd & 3rd - New York NY (W)",
"values": {
"location": "40.782606,-73.951235"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "165 Broadway - 1 Liberty - New York NY (W)",
"values": {
"location": "40.709727,-74.011395"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "1656 Broadway - New York NY (W)",
"values": {
"location": "40.762434,-73.983364"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "54th & Broadway - New York NY (W)",
"values": {
"location": "40.764275,-73.982361"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Limited Brands-NYC - New York NY",
"values": {
"location": "40.765219,-73.982025"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "19th & 8th - New York NY (W)",
"values": {
"location": "40.743218,-74.000605"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "60th & Broadway-II - New York NY (W)",
"values": {
"location": "40.769196,-73.982576"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "63rd & Broadway - New York NY (W)",
"values": {
"location": "40.771376,-73.982709"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "195 Broadway - New York NY (W)",
"values": {
"location": "40.710703,-74.009485"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "2 Broadway - New York NY (W)",
"values": {
"location": "40.704538,-74.01324"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "2 Columbus Ave. - New York NY (W)",
"values": {
"location": "40.769262,-73.984764"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "NY Plaza - New York NY (W)",
"values": {
"location": "40.702802,-74.012784"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "36th and Madison - New York NY (W)",
"values": {
"location": "40.748917,-73.982683"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "125th St. btwn Adam Clayton & FDB - New York NY",
"values": {
"location": "40.808952,-73.948229"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "70th & Broadway - New York NY (W)",
"values": {
"location": "40.777463,-73.982237"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "2138 Broadway - New York NY (W)",
"values": {
"location": "40.781078,-73.981167"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "118th & Frederick Douglas Blvd. - New York NY (W)",
"values": {
"location": "40.806176,-73.954109"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "42nd & Second - New York NY (W)",
"values": {
"location": "40.750069,-73.973393"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Broadway @ 81st - New York NY (W)",
"values": {
"location": "40.784972,-73.978987"
}
}
}
{
"dataset": "Starbucks",
"type": "add",
"body": {
"table": "Store",
"key": "Fashion Inst of Technology - New York NY",
"values": {
"location": "40.746948,-73.994557"
}
}
}
もう一つターミナルを開いて、jsonをDroonga engineに送信しましょう。
以下のようにしてstores.json
を送信します:
# droonga-request --tag starbucks stores.jsons
Elapsed time: 0.01101195
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.8918273",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.008872597
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9034681",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.008392207
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9126666",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.011983187
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9212565",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.008101728
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9338331",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.004175044
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9421282",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.017018749
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.946642",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.007583209
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9639654",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.00841723
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9719582",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.009108127
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9804838",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.005036642
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.989766",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.004036806
[
"droonga.message",
1393562553,
{
"inReplyTo": "1393562553.9952037",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.012368974
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562553.999501",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.004099008
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.0122097",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.027017019
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.016705",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.010383751
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.044215",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.004364288
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.0549927",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.003277611
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.0595262",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.007540272
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.063036",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.002973611
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.0707917",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.024142012
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.0739512",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.010329014
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.098288",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.004758853
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1089437",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.007113416
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.113922",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.007472331
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.121428",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.011560447
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1294332",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.006053761
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1413999",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.013611626
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1479707",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.007455591
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1624238",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.005440424
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1702914",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.005610303
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1760805",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.025479938
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.1822054",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.007125251
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2080746",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.009454133
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2158518",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.003632905
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2255347",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.003653783
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2293708",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.003643588
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2332237",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.003703875
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.237225",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.003402826
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2411628",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Elapsed time: 0.004817463
[
"droonga.message",
1393562554,
{
"inReplyTo": "1393562554.2447524",
"statusCode": 200,
"type": "add.result",
"body": true
}
]
Droonga engineを用いてスターバックスの店舗データベースを検索する準備ができました。
動作を確認してみましょう。クエリを以下のようなJSONファイルとして作成します。
search-all-stores.json:
{
"dataset": "Starbucks",
"type": "search",
"body": {
"queries": {
"stores": {
"source": "Store",
"output": {
"elements": [
"startTime",
"elapsedTime",
"count",
"attributes",
"records"
],
"attributes": ["_key"],
"limit": -1
}
}
}
}
}
Droonga Engine にリクエストを送信します:
# droonga-request search-all-stores.json
Elapsed time: 0.008286785
[
"droonga.message",
1393562604,
{
"inReplyTo": "1393562604.4970381",
"statusCode": 200,
"type": "search.result",
"body": {
"stores": {
"count": 40,
"records": [
[
"15th & Third - New York NY (W)"
],
[
"41st and Broadway - New York NY (W)"
],
[
"84th & Third Ave - New York NY (W)"
],
[
"Macy's 35th Street Balcony - New York NY"
],
[
"Second @ 81st - New York NY (W)"
],
[
"52nd & Seventh - New York NY (W)"
],
[
"1585 Broadway (47th) - New York NY (W)"
],
[
"54th & Broadway - New York NY (W)"
],
[
"60th & Broadway-II - New York NY (W)"
],
[
"63rd & Broadway - New York NY (W)"
],
[
"2 Columbus Ave. - New York NY (W)"
],
[
"NY Plaza - New York NY (W)"
],
[
"2138 Broadway - New York NY (W)"
],
[
"Broadway @ 81st - New York NY (W)"
],
[
"76th & Second - New York NY (W)"
],
[
"2nd Ave. & 9th Street - New York NY"
],
[
"150 E. 42nd Street - New York NY (W)"
],
[
"Macy's 6th Floor - Herald Square - New York NY (W)"
],
[
"Herald Square- Macy's - New York NY"
],
[
"Macy's 5th Floor - Herald Square - New York NY (W)"
],
[
"Marriott Marquis - Lobby - New York NY"
],
[
"85th & First - New York NY (W)"
],
[
"1656 Broadway - New York NY (W)"
],
[
"Limited Brands-NYC - New York NY"
],
[
"2 Broadway - New York NY (W)"
],
[
"36th and Madison - New York NY (W)"
],
[
"125th St. btwn Adam Clayton & FDB - New York NY"
],
[
"118th & Frederick Douglas Blvd. - New York NY (W)"
],
[
"Fashion Inst of Technology - New York NY"
],
[
"1st Avenue & 75th St. - New York NY (W)"
],
[
"West 43rd and Broadway - New York NY (W)"
],
[
"80th & York - New York NY (W)"
],
[
"Columbus @ 67th - New York NY (W)"
],
[
"45th & Broadway - New York NY (W)"
],
[
"92nd & 3rd - New York NY (W)"
],
[
"165 Broadway - 1 Liberty - New York NY (W)"
],
[
"19th & 8th - New York NY (W)"
],
[
"195 Broadway - New York NY (W)"
],
[
"70th & Broadway - New York NY (W)"
],
[
"42nd & Second - New York NY (W)"
]
]
}
}
}
]
店舗の名前が取得できました。エンジンは正しく動作しているようです。引き続き Protocol Adapter を構築して、検索リクエストをHTTPで受け付けられるようにしましょう。
HTTP Protocol Adapterとしてdroonga-http-server
を使用します。droonga-http-server
は、Node.js のパッケージです。
# npm install -g droonga-http-server
次に、サーバを起動します。
# droonga-http-server --port 3000 \
--receive-host-name=192.168.0.10 \
--droonga-engine-host-name=192.168.0.10 \
--default-dataset=Starbucks \
--daemon \
--pid-file $PWD/droonga-http-server.pid
準備が整いました。 Protocol Adapter に向けて HTTP 経由でリクエストを発行し、データベースに問い合わせを行ってみましょう。まずは Shops
テーブルの中身を取得してみます。以下のようなリクエストを用います。(attributes=_key
を指定しているのは「検索結果に _key
値を含めて返してほしい」という意味です。これがないと、records
に何も値がないレコードが返ってきてしまいます。attributes
パラメータには ,
区切りで複数の属性を指定することができます。attributes=_key,location
と指定することで、緯度経度もレスポンスとして受け取ることができます)
# curl "http://192.168.0.10:3000/tables/Store?attributes=_key&limit=-1"
{
"stores": {
"count": 40,
"records": [
[
"15th & Third - New York NY (W)"
],
[
"41st and Broadway - New York NY (W)"
],
[
"84th & Third Ave - New York NY (W)"
],
[
"Macy's 35th Street Balcony - New York NY"
],
[
"Second @ 81st - New York NY (W)"
],
[
"52nd & Seventh - New York NY (W)"
],
[
"1585 Broadway (47th) - New York NY (W)"
],
[
"54th & Broadway - New York NY (W)"
],
[
"60th & Broadway-II - New York NY (W)"
],
[
"63rd & Broadway - New York NY (W)"
],
[
"2 Columbus Ave. - New York NY (W)"
],
[
"NY Plaza - New York NY (W)"
],
[
"2138 Broadway - New York NY (W)"
],
[
"Broadway @ 81st - New York NY (W)"
],
[
"76th & Second - New York NY (W)"
],
[
"2nd Ave. & 9th Street - New York NY"
],
[
"150 E. 42nd Street - New York NY (W)"
],
[
"Macy's 6th Floor - Herald Square - New York NY (W)"
],
[
"Herald Square- Macy's - New York NY"
],
[
"Macy's 5th Floor - Herald Square - New York NY (W)"
],
[
"Marriott Marquis - Lobby - New York NY"
],
[
"85th & First - New York NY (W)"
],
[
"1656 Broadway - New York NY (W)"
],
[
"Limited Brands-NYC - New York NY"
],
[
"2 Broadway - New York NY (W)"
],
[
"36th and Madison - New York NY (W)"
],
[
"125th St. btwn Adam Clayton & FDB - New York NY"
],
[
"118th & Frederick Douglas Blvd. - New York NY (W)"
],
[
"Fashion Inst of Technology - New York NY"
],
[
"1st Avenue & 75th St. - New York NY (W)"
],
[
"West 43rd and Broadway - New York NY (W)"
],
[
"80th & York - New York NY (W)"
],
[
"Columbus @ 67th - New York NY (W)"
],
[
"45th & Broadway - New York NY (W)"
],
[
"92nd & 3rd - New York NY (W)"
],
[
"165 Broadway - 1 Liberty - New York NY (W)"
],
[
"19th & 8th - New York NY (W)"
],
[
"195 Broadway - New York NY (W)"
],
[
"70th & Broadway - New York NY (W)"
],
[
"42nd & Second - New York NY (W)"
]
]
}
}
count
の値からデータが全部で 36 件あることがわかります。records
に配列として検索結果が入っています。
もう少し複雑なクエリを試してみましょう。例えば、店名に「Columbus」を含む店舗を検索します。query
パラメータにクエリ Columbus
を、match_to
パラメータに検索対象として _key
を指定し、以下のようなリクエストを発行します。
# curl "http://192.168.0.10:3000/tables/Store?query=Columbus&match_to=_key&attributes=_key&limit=-1"
{
"stores": {
"count": 2,
"records": [
[
"Columbus @ 67th - New York NY (W)"
],
[
"2 Columbus Ave. - New York NY (W)"
]
]
}
}
以上 2 件が検索結果として該当することがわかりました。
Droonga HTTP Serverの詳細についてはリファレンスマニュアルを参照して下さい。
Ubuntu Linux 上に Droonga を構成するパッケージである droonga-engine と droonga-http-server をセットアップしました。 これらのパッケージを利用することで、HTTP Protocol Adapter と Droonga Engine からなるシステムを構築し、実際に検索を行いました。