なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

Monger + mLab + ClojureでMongoDBに触る

MongoDBはいわゆるNoSQLで、きっちり行と列を定めなければいけないRDBと違い、JSONをそのままぶっこめる。
今趣味で触っているプログラムに使おうと思い、Mongerをクライアントライブラリとして使用してみた。

準備編

Monger

ClojureのMongoDBクライアント側ライブラリ。使いはじめは以下のページから:
Monger, a Clojure MongoDB client: Connecting to MongoDB | MongoDB library for Clojure

project.cljに以下を追加するだけ

[com.novemberain/monger "3.1.0"]

mLab

MongoDBをクラウドで提供しているPaaS、今見たらTOYOTAも使ってるようだ。無料枠がある。
www.mlab.com

HerokuのAdd-onからmLabを使う

Herokuの側でAdd-onを追加したら、Herokuの環境変数MONGODB_URIに全ての認証情報が入っている。
うーん、これを使用してやればもっと簡単にできたな。

mLabのダッシュボードに入ると、以下のような情報がもらえる

Database: heroku_xxxxxxxx
To connect using the mongo shell:
mongo ds12345.mlab.com:12345/heroku_xxxxxxxx -u -p
To connect using a driver via the standard MongoDB URI (what's this?):
mongodb://:@ds12345.mlab.com:12345/heroku_xxxxxxxx

mLabでMongoDBのユーザーを作成する

自動作成する接続情報とは別にユーザーを作ることも出来る。

mLabの管理ポータルにログインする

  1. アカウントのページからデプロイのページへ(動きが正しければ、ユーザーを追加するためのデータベースに遷移するはず)
  2. 「ユーザー」タブをクリック
  3. 「データベースユーザーを追加」をクリック、新しいユーザーを追加する
  4. 追加したら以下のコマンドでリモートのMongoDBにログインできることを確認する
mongo ds12345.mlab.com:12345/heroku_xxxxxxxx -u <dbuser> -p<dbpassword>

コード片

これでやっと接続できる、わたしはとりあえず環境変数にいろいろ情報を与えて使ってみた。

  • mg/connect だと、ホスト名とポートをハッシュマップで渡すようだ
  • mg/connect-with-credentials だと、サーバ名は文字列にしないとだめなようだ
  • mg/connect-via-uri だと、環境変数MONGODB_URIが使えるのだと思う
  • let [db (or (System/getenv "DB_NAME") "")] とやると、環境変数から文字列が取れなかった時に空文字を入れられる
  • Rubyにおけるnilガードみたいなやつですね
  • とりあえずこれでJavaでいうところのConnectionがとれる
(ns sample
  (:gen-class
   :main false)
  (:require [clojure.string :as str]
            [monger.core :as mg]
            [monger.credentials :as mcred]))

(defn mongodb []
  (let [db   (or (System/getenv "DB_NAME") "")
        user (or (System/getenv "DB_USER") "")
        pass (or (System/getenv "DB_PASS") "")
        host (or (System/getenv "DB_HOST") "127.0.0.1")
        port (Integer/parseInt (or (System/getenv "DB_PORT") "27017"))]

    (if (or (str/blank? user) (str/blank? pass))
      ;; ユーザーやパスワードが設定されてないので開発環境
      (mg/connect {:host host :port port})
      ;; 本番環境
      (mg/connect-with-credentials (str host ":" port) (mcred/create user db pass))
    )))

結局接続するだけで今日は終わってしまった。レコードを作りたかったのだが。