2013/04/21

Common Lisp の MongoDB ドライバを作ってみた

cl-mongo があるのは知っていましたが、それでも Common Lisp の MongoDB ドライバを作ってみました。

Quicklisp には入ってません。

いろいろ足りないかもしれませんが、とりあえず動きます。仕事でログ解析に使ったりしています。

;; 他にも https://github.com/quek/ の下にある何かが必要かも・・・
(eval-when (:compile-toplevel :load-toplevel :execute)
;; https://github.com/quek/info.read-eval-print.bson
(ql:quickload :info.read-eval-print.bson)
;; https://github.com/quek/info.read-eval-print.mongo
(ql:quickload :info.read-eval-print.mongo))

(defpackage :mongo
(:use :cl)
;; SBCL の local-nicknames を使ってみたりする。これいいよね。
(:local-nicknames (:m :info.read-eval-print.mongo)
(:b :info.read-eval-print.bson)))

(in-package :mongo)

(defvar *connection* (m:connect "localhost:27017"))
;;⇒ *CONNECTION*

(defvar *db* (m:db *connection* "test"))
;;⇒ *DB*

(defvar *foo* (m:collection *db* "foo"))
;;⇒ *FOO*

;; 登録する
(loop for i from 1 to 10
do (m:insert *foo* (b:bson :a "hello" :b i)))
(m:insert *foo* (b:bson :a "world" :b 1))

;; 検索する。Series を使う。
(series:collect (m:scan-mongo *foo* nil))
;;⇒ ({"_id": ObjectId("51734E4BCF15ED0A74C21E61"), "a": "hello", "b": 1}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E62"), "a": "hello", "b": 2}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E63"), "a": "hello", "b": 3}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E64"), "a": "hello", "b": 4}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E65"), "a": "hello", "b": 5}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E66"), "a": "hello", "b": 6}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E67"), "a": "hello", "b": 7}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E68"), "a": "hello", "b": 8}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E69"), "a": "hello", "b": 9}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E6A"), "a": "hello", "b": 10}
;; {"_id": ObjectId("51734E4DCF15ED0A74C21E6B"), "a": "world", "b": 1})

(series:collect (m:scan-mongo *foo* (b:bson (m:$< :b 3) :a "hello")))
;;⇒ ({"_id": ObjectId("51734E4BCF15ED0A74C21E61"), "a": "hello", "b": 1}
;; {"_id": ObjectId("51734E4BCF15ED0A74C21E62"), "a": "hello", "b": 2})