ClojureでMongoDBにアクセスしてみる

MongoDBというのをちょっと触ってみたかったので、Clojureからアクセスしてみた。Clojureのライブラリにはcongomongoを使用。ググったらこれが出てきたので、ひとまずこれを使ってみた。

基本的にはcongomongoのページに書いてあったものをベースに、少しだけ変えています。

以下は、REPLから実行した模様。

実行結果1

user> (use 'somnium.congomongo)
nil
user> (mongo! :db "mydb")
true
user> (collections)
("system.indexes")
user> (fetch :robots)
()
user> (insert! :robots {:name "robby1"})
{:_id #<ObjectId 4d0c837dda33c172e7f7bc9b>, :name "robby1"}
user> (fetch :robots)
({:name "robby1", :_id #<ObjectId 4d0c837dda33c172e7f7bc9b>})
user> (collections)
("robots" "system.indexes")
user> (insert! :robots {:name "robby2"})
{:_id #<ObjectId 4d0c8398da33c172e8f7bc9b>, :name "robby2"}
user> (fetch :robots)
({:name "robby1", :_id #<ObjectId 4d0c837dda33c172e7f7bc9b>} {:name "robby2", :_id #<ObjectId 4d0c8398da33c172e8f7bc9b>})
user> (def robot (fetch-by-id "4d0c8398da33c172e8f7bc9b"))
(def robot (fetch-by-id :robots "4d0c8398da33c172e8f7bc9b"))
#'user/robot
user> robot
{:name "robby2", :_id #<ObjectId 4d0c8398da33c172e8f7bc9b>}
user> (update! :robots robot (merge robot {:name "asimo"}))
nil
user> (fetch :robots)
({:name "robby1", :_id #<ObjectId 4d0c837dda33c172e7f7bc9b>} {:name "asimo", :_id #<ObjectId 4d0c8398da33c172e8f7bc9b>})
user> (drop-coll! :robots)
nil
user> (collections)
("system.indexes")

ひとまず登録、更新をやってみた。最後は:robotsをバッサリ削除。

次に、update!を実行するときに、新しくname2という項目を追加した場合の実行結果。

実行結果2

user> (insert! :robots {:name "robby1"})
{:_id #<ObjectId 4d0c8586da33c172e9f7bc9b>, :name "robby1"}
user> 
nil
user> (fetch :robots)
({:name "robby1", :_id #<ObjectId 4d0c8586da33c172e9f7bc9b>})
user> (def robot (fetch-by-id :robots "4d0c8586da33c172e9f7bc9b"))
#'user/robot
user> robot
{:name "robby1", :_id #<ObjectId 4d0c8586da33c172e9f7bc9b>}
user> (update! :robots robot (merge robot { :name2 "robby-1"}))
nil
user> (fetch :robots)
({:name "robby1", :name2 "robby-1", :_id #<ObjectId 4d0c8586da33c172e9f7bc9b>})
user> (fetch :robots :as :json)
("{ \"_id\" : { \"$oid\" : \"4d0c8586da33c172e9f7bc9b\"} , \"name2\" : \"robby-1\" , \"name\" : \"robby1\"}")

Clojureのマップを使うことによって、データの登録、更新が非常に簡単に出来ますね。
RDBのように先にテーブル作って、カラム作ってとやる必要がないので、その辺りも扱いが楽そう。
JSON形式で出力した場合には、fetchするときに":as :json"を引数に渡せばOK。