2012/12/30

cl-mongo を series で

cl-mongo を series で

(defun order-kv (order)
(cond ((null order)
nil)
((atom order)
(cl-mongo:kv order 1))
(t
(apply #'cl-mongo:kv
(mapcar (lambda (x)
(if (atom x)
(cl-mongo:kv x 1)
(cl-mongo:kv (car x)
(if (eq :desc (cadr x)) -1 1))))
order)))))

(series::defS scan-mongo (collection query &key (skip 0) (limit 0) order)
"scan mongoDB collection."
(series::fragl
;; args
((collection) (query) (skip) (limit) (order))
;; rets
((doc t))
;; aux
((doc t) (cursor t) (count integer))
;; alt
()
;; prolog
((setq count 0)
(setq cursor (cl-mongo:db.find
collection
(aif (order-kv order)
(cl-mongo:kv (cl-mongo:kv "query" query)
(cl-mongo:kv "orderby" it))
query)
:skip skip
:limit limit)))
;; body
(L
(setq doc (pop (cadr cursor)))
(unless doc
(push nil (cadr cursor))
(if (zerop (cl-mongo::db.iterator cursor))
(go series::end)
(progn
(incf count (nth 7 (car cursor)))
(if (and (plusp limit) (<= limit count))
(go series::end)
(progn
(setq cursor (cl-mongo:db.iter cursor :limit (- limit count)))
(pop (cadr cursor))
(go L)))))))
;; epilog
((cl-mongo:db.stop cursor))
;; wraprs
()
;; impure
nil))

として

(iterate ((doc (scan-mongo "logs.app" (cl-mongo:$> "_id" last-id))))
(foo doc))

な感じ。