A Mongo client for clojure, lightly wrapping 3.11/4.0+ versions of the MongoDB Java Driver
In general, it will feel familiar to users of mongo clients like monger. Like our HTTP/2 client hato, the API is designed to be idiomatic and to make common tasks convenient, whilst still allowing the underlying client to be configured via native Java objects.
It was developed with the following goals:
mongo-driver-3 is used in production, but is also under development and the API may change slightly. Please try it out and raise any issues you may find.
For Leinengen, add this to your project.clj:
;; The underlying driver -- any newer version can also be used
[org.mongodb/mongodb-driver-sync "3.11.2"]
;; This wrapper library
[mongo-driver-3 "0.5.0"]
(ns my.app
(:require [mongo-driver-3.client :as mcl]))
We usually start by creating a client and connecting to a database with a connection string.
connect-to-db
is a convenience function that allows you to do this directly.
(mcl/connect-to-db "mongodb://localhost:27017/my-db")
; =>
; {
; :client - a MongoClient instance
; :db - a Database that you can pass to all the collection functions
; }
You can also create a client and get a DB separately:
;; Calling create without an arg will try and connect to the default host/port.
(def client (mcl/create "mongodb://localhost:27017"))
;; Create a db that you can pass around.
(def db (mcl/get-db client "my-db"))
All the collection functions closely mirror the naming in the corresponding java driver module.
They always take a db as the first argument, collection name as the second, and an optional map of options as the last. Full documentation of options can be found on cljdoc.
As an example:
(ns my.app
(:require [mongo-driver-3.collection :as mc]))
;; Insert some documents
(mc/insert-many db "test" [{:v "hello"} {:v "world"}])
;; Count all documents
(mc/count-documents db "test")
; => 2
;; Count with a query
(mc/count-documents db "test" {:v "hello"})
; => 1
;; Find the documents, returning a seq
(mc/find db "test" {} {:limit 1 :projection {:_id 0}})
; => ({:v "hello"})
;; Find the documents, returning the raw FindIterable response
(mc/find db "test" {} {:raw? true})
; => a MongoIterable
;; Find a single document or return nil
(mc/find-one db "test" {:v "world"} {:keywordize? false})
; => {"v" "world"}
While most options are supported directly, sometimes you may need to some extra control. In such cases, you can pass in a configured java options object. Any other options will be applied on top of this object.
;; These are equivalent
(mc/rename db "test" "new-test" {:drop-target? true})
(mc/rename db "test" "new-test" {:rename-collection-options (.dropTarget (RenameCollectionOptions.) true)})
Again, read the docs for full API documentation.
Many mongo queries take operators like $eq
and $gt
. These are exposed in the mongo-driver-3.operator
namespace.
(ns my.app
(:require [mongo-driver-3.collection :as mc]
[mongo-driver-3.operator :refer [$gt]))
(mc/find db "test" {:a {$gt 3}})
;; This is equivalent to, but with less chance of error than:
(mc/find db "test" {:a {"$gt" 3}})
The bulk API is similar to the mongo shell, except each operation is defined as a 2-tuple rather than a map.
;; Execute a mix of operations in one go
(bulk-write [[:insert-one {:document {:a 1}}]
[:delete-one {:filter {:a 1}}]
[:delete-many {:filter {:a 1}}]
[:update-one {:filter {:a 1} :update {:$set {:a 2}}}]
[:update-many {:filter {:a 1} :update {:$set {:a 2}}}]
[:replace-one {:filter {:a 1} :replacement {:a 2}}]])
; => a BulkWriteResult
;; Each operation can take the same options as their respective functions
(bulk-write [[:update-one {:filter {:a 1} :update {:$set {:a 2}} :upsert? true}]
[:update-many {:filter {:a 1} :update {:$set {:a 2}} :upsert? true}]
[:replace-one {:filter {:a 1} :replacement {:a 2} :upsert? true}]])
You can create a session to perform multi-document transactions, where all operations either succeed or none are persisted.
It is important to
use with-open
so the session is closed after both successful and failed transactions.
;; Inserts 2 documents into a collection
(with-open [s (mg/start-session client)]
(mg/with-transaction s
(fn []
(mc/insert-one my-db "coll" {:name "hello"} {:session s})
(mc/insert-one my-db "coll" {:name "world"} {:session s}))))
Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close