ArangoDBはスキーマフリーでMongoDBやCouchDBと比較されることが多いデータベースです。グラフも扱えるということで、試しに使ってみました。
インストール
主要なOSについては、インストーラもしくはパッケージが用意されています。今回はUbuntu12.04にパッケージをインストールしました。
1 2 3 4 5 |
$ sudo echo 'deb http://www.arangodb.org/repositories/stable/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/arangodb.list $ wget http://www.arangodb.org/repositories/stable/xUbuntu_12.04/Release.key $ sudo apt-key add - < Release.key $ apt-get update $ apt-get install arangodb |
インストール後、起動してデフォルトで8529番ポートで待ち受けます。
CRUD
ArangoDBもMongoDBなどのドキュメント指向DB同様、RDBのテーブルに相当するものをコレクション、レコードに相当するものをドキュメントと呼んでいます。
Webのインターフェイス(http://localhost:8529/)もありますが、arangoshを使ってデータを操作してみます。arangoshを起動すると、パスワードを聞かれますが、設定を変更していなければノーパスでログインできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
$ arangosh Please specify a password: _ __ _ _ __ __ _ _ __ __ _ ___ ___| |__ / _` | '__/ _` | '_ \ / _` |/ _ \/ __| '_ \ | (_| | | | (_| | | | | (_| | (_) \__ \ | | | \__,_|_| \__,_|_| |_|\__, |\___/|___/_| |_| |___/ Welcome to arangosh 1.3.3. Copyright (c) triAGENS GmbH Using Google V8 3.16.14 JavaScript engine, READLINE 6.2, ICU 4.8.1.1 Connected to ArangoDB 'tcp://localhost:8529' version 1.3.3 ------------------------------------- Help ------------------------------------- Predefined objects: arango: ArangoConnection db: ArangoDatabase Example: > db._collections(); list all collections > db.<coll_name>.all().toArray(); list all documents > id = db.<coll_name>.save({ ... }); save a document > db.<coll_name>.remove(<_id>); delete a document > db.<coll_name>.document(<_id>); get a document > db.<coll_name>.replace(<_id>, {...}); overwrite a document > db.<coll_name>.update(<_id>, {...}); partially update a document > help show help pages > exit Note: collection names may be cached in arangosh. To refresh them, issue: > db._collections(); arangosh> |
まず、コレクションを作成。
1 2 |
arangosh> db._create("example"); [ArangoCollection 23182034, "example" (type document, status loaded)] |
作成したコレクションにドキュメントを登録。
1 2 3 4 5 6 7 8 |
arangosh> db.example.save({hello:"world"}); { "error" : false, "_id" : "example/24361682", "_rev" : "24361682", "_key" : "24361682" } arangosh> db.example.save({name:"taro", age:30 }); { "error" : false, "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362" } arangosh> db.example.save({name:"hanako", age:25 }); { "error" : false, "_id" : "example/24820434", "_rev" : "24820434", "_key" : "24820434" } |
登録したレコードを取り出してみます。start_pretty_print()は結果を整形して出力するためのコマンドです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
arangosh> start_pretty_print(); using pretty printing arangosh> db.example.all().toArray(); [ { "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362", "age" : 30, "name" : "taro" }, { "_id" : "example/24361682", "_rev" : "24361682", "_key" : "24361682", "hello" : "world" }, { "_id" : "example/24820434", "_rev" : "24820434", "_key" : "24820434", "age" : 25, "name" : "hanako" } ] |
ドキュメントをIDで取り出してみます。IDで取り出す場合は、ドキュメントが返ってきますのでtoArray()なして表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
arangosh> db.example.document("24689362"); { "age" : 30, "name" : "taro", "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362" } arangosh> db._document("example/24689362"); { "age" : 30, "name" : "taro", "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362" } |
属性に一致するドキュメントの取り出し。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
arangosh> db.example.byExample({name:"taro"}).toArray(); [ { "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362", "age" : 30, "name" : "taro" } ] arangosh> db.example.byExample({name:"jiro"}).toArray(); [ ] |
より複雑な条件で検索するにはAQLという問い合わせ言語使います。AQLの詳しい文法はこちら。
1 2 3 4 5 6 7 8 9 10 |
arangosh> db._query('FOR user IN example FILTER user.age >=30 RETURN user').toArray(); [ { "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362", "age" : 30, "name" : "taro" } ] |
ドキュメントの更新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
arangosh> a1 = db._document("example/24689362"); { "age" : 30, "name" : "taro", "_id" : "example/24689362", "_rev" : "24689362", "_key" : "24689362" } arangosh> db.example.update(a1, {name:"jiro",age:30}); { "error" : false, "_id" : "example/24689362", "_rev" : "23718554346", "_key" : "24689362" } arangosh> db.example.toArray(); [ { "_id" : "example/24689362", "_rev" : "23718554346", "_key" : "24689362", "age" : 30, "name" : "jiro" }, { "_id" : "example/24361682", "_rev" : "24361682", "_key" : "24361682", "hello" : "world" }, { "_id" : "example/24820434", "_rev" : "24820434", "_key" : "24820434", "age" : 25, "name" : "hanako" } ] |
ドキュメントの削除。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
arangosh> a1 = db._document("example/24689362"); { "age" : 30, "name" : "jiro", "_id" : "example/24689362", "_rev" : "23718554346", "_key" : "24689362" } arangosh> db.example.remove(a1); true arangosh> db.example.toArray(); [ { "_id" : "example/24361682", "_rev" : "24361682", "_key" : "24361682", "hello" : "world" }, { "_id" : "example/24820434", "_rev" : "24820434", "_key" : "24820434", "age" : 25, "name" : "hanako" } ] |
データのインポート
もう少し大きなデータを入れて検索してみます。こちらのサンプルデータを使います。いくつかサンプルデータがありますが、主要都市の緯度経度の情報を登録してみます。レコード数は約30万件です。
インポートできるのはjson, csv, tsv(タブ区切り)の3種類で、csvとtsvは属性名を1行目に入れて、データは2行目から始めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
arangoimp --file GeoLiteCity.csv --collection=cities --create-collection=true --type=csv Please specify a password: Connected to ArangoDB 'tcp://127.0.0.1:8529' Version 1.3.3 ---------------------------------------- collection: cities create: yes file: GeoLiteCity.csv type: csv quote: " separator: , connect timeout: 3 request timeout: 300 ---------------------------------------- Starting CSV import... created: 316848 errors: 0 total: 316849 |
検索の注意点
上で登録したデータから”Tokyo”を抜き出してみます。このとき、byExample()による検索とAQLによる検索ができますが、それぞれ所要時間を計測してみます。
byExample()による検索
1 2 |
arangosh> d = new Date();ts=d.getTime();db.cities.byExample({name:"Tokyo"}).toArray();d = new Date();te=d.getTime();print(te - ts); 96 |
AQLによる検索
1 2 |
arangosh> d = new Date();ts=d.getTime();db._query('FOR city IN cities FILTER city.city == "Tokyo" RETURN city').toArray();d = new Date();te=d.getTime();print(te - ts); 1903 |
byExample()では96msecのところが、AQLでは1903msecと大きな開きがあります。AQLを使わなくても済むところでは、AQLは使わないのが鉄則です。
ちなみにMySQLでキャッシュを無効にして試したところ、140msecでした。
次回は”edge”と呼ばれる特殊なドキュメントについてみていく予定です。
おまけ
最初のほうでWebのインターフェイスもあると書きましたが、Webのインターフェイスは、http://localhost:8529/にアクセスすれば使えます。