add aggregate; update docs

This commit is contained in:
George Narroway 2019-11-14 20:09:01 +08:00
parent e931d78bf0
commit 62b879583f
5 changed files with 269 additions and 253 deletions

View file

@ -1,9 +1,20 @@
# Change Log # Change Log
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
## 0.2.0 - 2019-11-14 ## [Unreleased]
### Added ### Added
- def some operators - Added aggregate function
- `skip` option to `find`
### Changed
- Better docs for cljdoc
- Merged `find-maps` into `find`
- Added ? suffix to boolean params
- Renamed `find-one-as-map` to `find-one`
## [0.2.0] - 2019-11-14
### Added
- expose operators
## 0.1.0 - 2019-11-14 ## 0.1.0 - 2019-11-14
### Added ### Added

View file

@ -19,7 +19,7 @@ It was developed with the following goals:
## Status ## Status
mongo-driver-3 is under active development but the existing API is unlikely to break. mongo-driver-3 is under active development and the API may change.
Please try it out and raise any issues you may find. Please try it out and raise any issues you may find.
## Usage ## Usage
@ -31,7 +31,7 @@ For Leinengen, add this to your project.clj:
[org.mongodb/mongodb-driver-sync "3.11.0"] [org.mongodb/mongodb-driver-sync "3.11.0"]
;; This wrapper library ;; This wrapper library
[mongo-driver-3 "0.1.0"] [mongo-driver-3 "0.2.0"]
``` ```
## License ## License

View file

@ -1,4 +1,4 @@
(defproject mongo-driver-3 "0.2.0" (defproject mongo-driver-3 "0.3.0-SNAPSHOT"
:description "A Clojure wrapper for the Java MongoDB driver 3.11+." :description "A Clojure wrapper for the Java MongoDB driver 3.11+."
:url "https://github.com/gnarroway/mongo-driver-3" :url "https://github.com/gnarroway/mongo-driver-3"
:license {:name "The MIT License" :license {:name "The MIT License"

View file

@ -2,7 +2,7 @@
(:refer-clojure :exclude [find empty? drop]) (:refer-clojure :exclude [find empty? drop])
(:import (clojure.lang Ratio Keyword Named IPersistentMap) (:import (clojure.lang Ratio Keyword Named IPersistentMap)
(com.mongodb ReadConcern ReadPreference WriteConcern MongoNamespace) (com.mongodb ReadConcern ReadPreference WriteConcern MongoNamespace)
(com.mongodb.client MongoDatabase MongoCollection TransactionBody MongoCursor) (com.mongodb.client MongoDatabase MongoCollection TransactionBody)
(com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions CreateCollectionOptions RenameCollectionOptions IndexOptions IndexModel UpdateOptions ReplaceOptions) (com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions CreateCollectionOptions RenameCollectionOptions IndexOptions IndexModel UpdateOptions ReplaceOptions)
(java.util List Collection) (java.util List Collection)
(java.util.concurrent TimeUnit) (java.util.concurrent TimeUnit)
@ -47,7 +47,7 @@
input)) input))
(defprotocol ConvertFromDocument (defprotocol ConvertFromDocument
(from-document [input keywordize] "Converts given Document to Clojure")) (from-document [input keywordize?] "Converts given Document to Clojure"))
(extend-protocol ConvertFromDocument (extend-protocol ConvertFromDocument
nil nil
@ -62,12 +62,12 @@
(.bigDecimalValue input)) (.bigDecimalValue input))
List List
(from-document [^List input keywordize] (from-document [^List input keywordize?]
(vec (map #(from-document % keywordize) input))) (vec (map #(from-document % keywordize?) input)))
Document Document
(from-document [^Document input keywordize] (from-document [^Document input keywordize?]
(reduce (if keywordize (reduce (if keywordize?
(fn [m ^String k] (fn [m ^String k]
(assoc m (keyword k) (from-document (.get input k) true))) (assoc m (keyword k) (from-document (.get input k) true)))
(fn [m ^String k] (fn [m ^String k]
@ -132,8 +132,8 @@
write-concern write-concern
(WriteConcern/valueOf (name write-concern))))] (WriteConcern/valueOf (name write-concern))))]
(-> (or wc (WriteConcern/ACKNOWLEDGED)) (-> (or wc (WriteConcern/ACKNOWLEDGED))
(#(if (some? w) (.withW % w) %)) (#(if w (.withW % w) %))
(#(if (some? w-timeout-ms) (.withWTimeout % w-timeout-ms (TimeUnit/MILLISECONDS)) %)) (#(if w-timeout-ms (.withWTimeout % w-timeout-ms (TimeUnit/MILLISECONDS)) %))
(#(if (some? journal?) (.withJournal % journal?) %)))))) (#(if (some? journal?) (.withJournal % journal?) %))))))
(defn collection (defn collection
@ -165,6 +165,35 @@
;;; CRUD functions ;;; CRUD functions
(defn aggregate
"Aggregates documents according to the specified aggregation pipeline and returns an AggregateIterable.
Arguments:
- `db` is a MongoDatabase
- `coll` is a collection namee
- `q` is a map representing a query.
- `opts` (optional), a map of:
- `:allow-disk-use?` whether to allow writing temporary files
- `:batch-size` Documents to return per batch, e.g. 1
- `:bypass-document-validation?` Boolean
- `:keywordize?` keywordize the keys of return results, default: true
- `:raw?` return the mongo AggregateIterable directly instead of processing into a seq, default: false
- `:session` a ClientSession"
([^MongoDatabase db coll pipeline]
(aggregate db coll pipeline {}))
([^MongoDatabase db coll pipeline opts]
(let [{:keys [session allow-disk-use? batch-size bypass-document-validation? keywordize? raw?] :or {keywordize? true raw? false}} opts
it (-> (if session
(.aggregate (collection db coll opts) session (document pipeline))
(.aggregate (collection db coll opts) (document pipeline)))
(#(if (some? allow-disk-use?) (.allowDiskUse % allow-disk-use?) %))
(#(if batch-size (.batchSize % batch-size) %))
(#(if (some? bypass-document-validation?) (.bypassDocumentValidation % bypass-document-validation?) %)))]
(if-not raw?
(map (fn [x] (from-document x keywordize?)) (seq it))
it))))
(defn ->CountOptions (defn ->CountOptions
"Coerce options map into CountOptions. See `count-documents` for usage." "Coerce options map into CountOptions. See `count-documents` for usage."
@ -180,22 +209,19 @@
(defn count-documents (defn count-documents
"Count documents in a collection, optionally matching a filter query `q`. "Count documents in a collection, optionally matching a filter query `q`.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:hint an index name (string) hint or specification (map) - `q` is a map representing a query.
:max-time-ms max amount of time to allow the query to run, in milliseconds - `opts` (optional), a map of:
:skip number of documents to skip before counting - `:hint` an index name (string) hint or specification (map)
:limit max number of documents to count - `:max-time-ms` max amount of time to allow the query to run, in milliseconds
- `:skip` number of documents to skip before counting
:count-options a CountOptions, for configuring directly. If specified, any - `:limit` max number of documents to count
other query options will be applied to it. - `:count-options` a CountOptions, for configuring directly. If specified, any
other [preceding] query options will be applied to it.
-- other options - `:session` a ClientSession
:session a ClientSession
Additionally takes options specified in `collection`." Additionally takes options specified in `collection`."
([^MongoDatabase db coll] ([^MongoDatabase db coll]
@ -215,20 +241,18 @@
opts)) opts))
(defn delete-one (defn delete-one
"Deletes a single document from a collection and returns a DeletedResult. "Deletes a single document from a collection and returns a DeleteResult.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to match documents to delete.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:delete-options a DeleteOptions for configuring directly. - `q` is a map representing a query.
- `opts` (optional), a map of:
- `:delete-options` A DeleteOptions for configuring directly.
- `:session` A ClientSession
-- other options Additionally takes options specified in `collection`"
:session A ClientSession
Additionally takes options specified in `collection`."
([^MongoDatabase db coll q] ([^MongoDatabase db coll q]
(delete-one db coll q {})) (delete-one db coll q {}))
([^MongoDatabase db coll q opts] ([^MongoDatabase db coll q opts]
@ -239,16 +263,14 @@
(defn delete-many (defn delete-many
"Deletes multiple documents from a collection and returns a DeleteResult. "Deletes multiple documents from a collection and returns a DeleteResult.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to match documents to delete.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:delete-options A DeleteOptions for configuring directly. - `q` is a map representing a query.
- `opts` (optional), a map of:
-- other options - `:delete-options` A DeleteOptions for configuring directly.
:session A ClientSession - `:session` A ClientSession
Additionally takes options specified in `collection`" Additionally takes options specified in `collection`"
([^MongoDatabase db coll q] ([^MongoDatabase db coll q]
@ -259,63 +281,47 @@
(.deleteMany (collection db coll opts) (document q) (->DeleteOptions opts))))) (.deleteMany (collection db coll opts) (document q) (->DeleteOptions opts)))))
(defn find (defn find
"Finds documents and returns a FindIterable. "Finds documents and returns a seq of maps, unless configured otherwise.
This is a low level function that returns the result directly from the underling driver. Arguments:
Use `find-maps` to do some post-processing, e.g. returning a lazy seq
of clojure maps with keyword keys.
`db` is a MongoDatabase - `db` is a MongoDatabase
`coll` is a collection name - `coll` is a collection name
`q` is a map representing a query. - `q` is a map representing a query.
- `opts` (optional), a map of:
- `:limit` Max number of documents to return, e.g. 1
- `:skip` Number of documents to skip, e.g. 1
- `:sort` document representing sort order, e.g. {:timestamp -1}
- `:projection` document representing fields to return, e.g. {:_id 0}
- `:keywordize?` keywordize the keys of return results, default: true
- `:raw?` return the mongo FindIterable directly instead of processing into a seq, default: false
- `:session` a ClientSession
Takes an options map: Additionally takes options specified in `collection`."
:limit Number of results, e.g. 1
:sort document representing sort order, e.g. {:timestamp -1}
:projection document representing fields to return, e.g. {:_id 0}"
([^MongoDatabase db coll q] ([^MongoDatabase db coll q]
(find db coll q {})) (find db coll q {}))
([^MongoDatabase db coll q opts] ([^MongoDatabase db coll q opts]
(let [{:keys [limit sort projection session]} opts] (let [{:keys [limit skip sort projection session keywordize? raw?] :or {keywordize? true raw? false}} opts]
(-> (if session (let [it (-> (if session
(.find (collection db coll opts) session (document q)) (.find (collection db coll opts) session (document q))
(.find (collection db coll opts) (document q))) (.find (collection db coll opts) (document q)))
(#(if limit (.limit % limit) %)) (#(if limit (.limit % limit) %))
(#(if skip (.skip % skip) %))
(#(if sort (.sort % (document sort)) %)) (#(if sort (.sort % (document sort)) %))
(#(if projection (.projection % (document projection)) %)))))) (#(if projection (.projection % (document projection)) %)))]
(defn find-maps (if-not raw?
"Finds documents and returns them as a clojure seq of maps. (map (fn [x] (from-document x keywordize?)) (seq it))
it)))))
Takes the same options as `find`, as well as: (defn find-one
:keywordize keywordize the keys of returns results, default: true
:session a ClientSession
Additionally takes options specified in `collection`."
([^MongoDatabase db coll q]
(find-maps db coll q {}))
([^MongoDatabase db coll q opts]
(let [{:keys [keywordize] :or {keywordize true}} opts]
(with-open [^MongoCursor iterator (.iterator (find db coll q opts))]
(doall (map (fn [x] (from-document x keywordize)) (iterator-seq iterator)))))))
(defn find-one-as-map
"Finds a single document and returns it as a clojure map, or nil if not found. "Finds a single document and returns it as a clojure map, or nil if not found.
Takes the same options as `find`, as well as: Takes the same options as `find`."
:keywordize keywordize the keys of returns results, default: true
:session a ClientSession
Additionally takes options specified in `collection`."
([^MongoDatabase db coll q] ([^MongoDatabase db coll q]
(find-one-as-map db coll q {})) (find-one db coll q {}))
([^MongoDatabase db coll q opts] ([^MongoDatabase db coll q opts]
(let [{:keys [keywordize] :or {keywordize true}} opts] (first (find db coll q (assoc opts :limit 1 :raw? false)))))
(-> (find db coll q opts)
(.first)
(from-document keywordize)))))
(defn ->FindOneAndUpdateOptions (defn ->FindOneAndUpdateOptions
"Coerce options map into FindOneAndUpdateOptions. See `find-one-and-update` for usage." "Coerce options map into FindOneAndUpdateOptions. See `find-one-and-update` for usage."
@ -331,35 +337,32 @@
(defn find-one-and-update (defn find-one-and-update
"Atomically find a document (at most one) and modify it. "Atomically find a document (at most one) and modify it.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to find the document to update
`update` is a map representing an update. The update to apply must include only update operators.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:upsert? whether to insert a new document if nothing is found, default: false - `q` is a map representing a query.
:return-new? whether to return the document after update (insead of its state before the update), default: false - `update` is a map representing an update. The update to apply must include only update operators.
:sort map representing sort order, e.g. {:timestamp -1} - `opts` (optional), a map of:
:projection map representing fields to return, e.g. {:_id 0} - `:upsert?` whether to insert a new document if nothing is found, default: false
- `:return-new?` whether to return the document after update (insead of its state before the update), default: false
- `:sort` map representing sort order, e.g. {:timestamp -1}
- `:projection` map representing fields to return, e.g. {:_id 0}
- `:find-one-and-update-options` A FindOneAndUpdateOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it.
- `:keywordize?` keywordize the keys of return results, default: true
- `:session` a ClientSession
:find-one-and-update-options A FindOneAndUpdateOptions for configuring directly. If specified, Additionally takes options specified in `collection`."
any other query options will be applied to it.
-- other options
:keywordize keywordize the keys of returns results, default: true
:session a ClientSession
Additionally takes options specified in `collection`"
([^MongoDatabase db coll q update] ([^MongoDatabase db coll q update]
(find-one-and-update db coll q update {})) (find-one-and-update db coll q update {}))
([^MongoDatabase db coll q update opts] ([^MongoDatabase db coll q update opts]
(let [{:keys [keywordize session] :or {keywordize true}} opts (let [{:keys [keywordize? session] :or {keywordize? true}} opts
opts' (->FindOneAndUpdateOptions opts)] opts' (->FindOneAndUpdateOptions opts)]
(-> (if session (-> (if session
(.findOneAndUpdate (collection db coll opts) session (document q) (document update) opts') (.findOneAndUpdate (collection db coll opts) session (document q) (document update) opts')
(.findOneAndUpdate (collection db coll opts) (document q) (document update) opts')) (.findOneAndUpdate (collection db coll opts) (document q) (document update) opts'))
(from-document keywordize))))) (from-document keywordize?)))))
(defn ->FindOneAndReplaceOptions (defn ->FindOneAndReplaceOptions
"Coerce options map into FindOneAndReplaceOptions. See `find-one-and-replace` for usage." "Coerce options map into FindOneAndReplaceOptions. See `find-one-and-replace` for usage."
@ -375,35 +378,32 @@
(defn find-one-and-replace (defn find-one-and-replace
"Atomically find a document (at most one) and replace it. "Atomically find a document (at most one) and replace it.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to find the document to update
`doc` is a new document to add.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:upsert? whether to insert a new document if nothing is found, default: false - `q` is a map representing a query.
:return-new? whether to return the document after update (insead of its state before the update), default: false - `doc` is a new document to add.
:sort map representing sort order, e.g. {:timestamp -1} - `opts` (optional), a map of:
:projection map representing fields to return, e.g. {:_id 0} - `:upsert?` whether to insert a new document if nothing is found, default: false
- `:return-new?` whether to return the document after update (insead of its state before the update), default: false
- `:sort` map representing sort order, e.g. {:timestamp -1}
- `:projection` map representing fields to return, e.g. {:_id 0}
- `:find-one-and-replace-options` A FindOneAndReplaceOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it.
- `:keywordize?` keywordize the keys of return results, default: true
- `:session` a ClientSession
:find-one-and-replace-options A FindOneAndReplaceOptions for configuring directly. If specified, Additionally takes options specified in `collection`."
any other query options will be applied to it.
-- other options
:keywordize keywordize the keys of returns results, default: true
:session a ClientSession
Additionally takes options specified in `collection`"
([^MongoDatabase db coll q doc] ([^MongoDatabase db coll q doc]
(find-one-and-replace db coll q doc {})) (find-one-and-replace db coll q doc {}))
([^MongoDatabase db coll q doc opts] ([^MongoDatabase db coll q doc opts]
(let [{:keys [keywordize session] :or {keywordize true}} opts (let [{:keys [keywordize? session] :or {keywordize? true}} opts
opts' (->FindOneAndReplaceOptions opts)] opts' (->FindOneAndReplaceOptions opts)]
(-> (if session (-> (if session
(.findOneAndReplace (collection db coll opts) session (document q) (document doc) opts') (.findOneAndReplace (collection db coll opts) session (document q) (document doc) opts')
(.findOneAndReplace (collection db coll opts) (document q) (document doc) opts')) (.findOneAndReplace (collection db coll opts) (document q) (document doc) opts'))
(from-document keywordize))))) (from-document keywordize?)))))
(defn ->InsertOneOptions (defn ->InsertOneOptions
"Coerce options map into InsertOneOptions. See `insert-one` for usage." "Coerce options map into InsertOneOptions. See `insert-one` for usage."
@ -414,22 +414,19 @@
opts)) opts))
(defn insert-one (defn insert-one
"Inserts a single document into a collection. "Inserts a single document into a collection, and returns nil.
If the document does not have an _id field, it will be auto-generated by the underlying driver. If the document does not have an _id field, it will be auto-generated by the underlying driver.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`doc` is a map to insert
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:bypass-document-validation? Boolean - `doc` is a map to insert.
- `opts` (optional), a map of:
:insert-one-options An InsertOneOptions for configuring directly. If specified, - `:bypass-document-validation?` Boolean
any other query options will be applied to it. - `:insert-one-options` An InsertOneOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it.
-- other options - `:session` A ClientSession
:session A ClientSession
Additionally takes options specified in `collection`." Additionally takes options specified in `collection`."
([^MongoDatabase db coll doc] ([^MongoDatabase db coll doc]
@ -453,20 +450,17 @@
"Inserts multiple documents into a collection. "Inserts multiple documents into a collection.
If a document does not have an _id field, it will be auto-generated by the underlying driver. If a document does not have an _id field, it will be auto-generated by the underlying driver.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`docs` is a collection of maps to insert
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:bypass-document-valiation? Boolean - `docs` is a collection of maps to insert
:ordered? Boolean whether serve should insert documents in order provided (default true) - `opts` (optional), a map of:
- `:bypass-document-validation?` Boolean
:insert-many-options An InsertManyOptions for configuring directly. If specified, - `:ordered?` Boolean whether serve should insert documents in order provided (default true)
any other query options will be applied to it. - `:insert-many-options` An InsertManyOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it.
-- other options - `:session` A ClientSession
:session A ClientSession
Additionally takes options specified in `collection`" Additionally takes options specified in `collection`"
([^MongoDatabase db coll docs] ([^MongoDatabase db coll docs]
@ -487,23 +481,20 @@
opts)) opts))
(defn replace-one (defn replace-one
"Replace a single document. "Replace a single document in a collection and returns an UpdateResult.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to find the document to update
`doc` is a new document to add.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:upsert? whether to insert a new document if nothing is found, default: false - `q` is a map representing a query.
:bypass-document-validation? - `doc` is a new document to add.
- `opts` (optional), a map of:
:eplace-options A ReplaceOptions for configuring directly. If specified, - `:upsert?` whether to insert a new document if nothing is found, default: false
any other query options will be applied to it. - `:bypass-document-validation?` Boolean
- `:replace-options` A ReplaceOptions for configuring directly. If specified,
-- other options any other [preceding[ query options will be applied to it.
:session a ClientSession - `:session` a ClientSession
Additionally takes options specified in `collection`" Additionally takes options specified in `collection`"
([^MongoDatabase db coll q doc] ([^MongoDatabase db coll q doc]
@ -514,7 +505,7 @@
(.replaceOne (collection db coll opts) (document q) (document doc) (->ReplaceOptions opts))))) (.replaceOne (collection db coll opts) (document q) (document doc) (->ReplaceOptions opts)))))
(defn ->UpdateOptions (defn ->UpdateOptions
"Coerce options map into UpdateOptions. See `updatee-one` and `update-many` for usage." "Coerce options map into UpdateOptions. See `update-one` and `update-many` for usage."
[{:keys [update-options upsert? bypass-document-validation?]}] [{:keys [update-options upsert? bypass-document-validation?]}]
(let [opts (or update-options (UpdateOptions.))] (let [opts (or update-options (UpdateOptions.))]
(when (some? upsert?) (.upsert opts upsert?)) (when (some? upsert?) (.upsert opts upsert?))
@ -523,25 +514,22 @@
opts)) opts))
(defn update-one (defn update-one
"Updates a single document from a collection and returns a UpdateResult. "Updates a single document in a collection and returns an UpdateResult.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to match documents to update.
`update` is a map representing an update. The update to apply must include only update operators.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:upsert? Boolean whether to insert a new document if there are no matches to the query - `q` is a map representing a query.
:bypass-document-validation? Boolean - `update` is a map representing an update. The update to apply must include only update operators.
- `opts` (optional), a map of:
- `:upsert?` whether to insert a new document if nothing is found, default: false
- `:bypass-document-validation?` Boolean
- `:update-options` An UpdateOptions for configuring directly. If specified,
any other [preceding[ query options will be applied to it.
- `:session` a ClientSession
:update-options an UpdateOptions for configuring directly. If specified, Additionally takes options specified in `collection`"
any other query options will be applied to it.
-- other options
:session A ClientSession
Additionally takes options specified in `collection`."
([^MongoDatabase db coll q update] ([^MongoDatabase db coll q update]
(update-one db coll q update {})) (update-one db coll q update {}))
([^MongoDatabase db coll q update opts] ([^MongoDatabase db coll q update opts]
@ -550,25 +538,22 @@
(.updateOne (collection db coll opts) (document q) (document update) (->UpdateOptions opts))))) (.updateOne (collection db coll opts) (document q) (document update) (->UpdateOptions opts)))))
(defn update-many (defn update-many
"Updates many documents from a collection and returns a UpdateResult. "Updates many documents in a collection and returns an UpdateResult.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`q` is a map representing a query to match documents to update.
`update` is a map representing an update. The update to apply must include only update operators.
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:upsert? Boolean whether to insert a new document if there are no matches to the query - `q` is a map representing a query.
:bypass-document-validation? Boolean - `update` is a map representing an update. The update to apply must include only update operators.
- `opts` (optional), a map of:
- `:upsert?` whether to insert a new document if nothing is found, default: false
- `:bypass-document-validation?` Boolean
- `:update-options` An UpdateOptions for configuring directly. If specified,
any other [preceding[ query options will be applied to it.
- `:session` a ClientSession
:update-options an UpdateOptions for configuring directly. If specified, Additionally takes options specified in `collection`"
any other query options will be applied to it.
-- other options
:session A ClientSession
Additionally takes options specified in `collection`."
([^MongoDatabase db coll q update] ([^MongoDatabase db coll q update]
(update-many db coll q {})) (update-many db coll q {}))
([^MongoDatabase db coll q update opts] ([^MongoDatabase db coll q update opts]
@ -591,14 +576,16 @@
(defn create (defn create
"Creates a collection "Creates a collection
Takes an options map: Arguments:
-- query options
:capped? Boolean whether to create a capped collection
:max-documents max documents for a capped collection
:max-size-bytes max collection size in bytes for a capped collection
:create-collection-options A CreateCollectionOptions for configuring directly. If specified, - `db` is a MongoDatabase
any other query options will be applied to it" - `coll` is a collection name
- `opts` (optional), a map of:
- `:capped?` Boolean whether to create a capped collection
- `:max-documents` max documents for a capped collection
- `:max-size-bytes` max collection size in bytes for a capped collection
- `:create-collection-options` A CreateCollectionOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it"
([^MongoDatabase db coll] ([^MongoDatabase db coll]
(create db coll {})) (create db coll {}))
([^MongoDatabase db coll opts] ([^MongoDatabase db coll opts]
@ -616,12 +603,15 @@
(defn rename (defn rename
"Renames `coll` to `new-coll` in the same DB. "Renames `coll` to `new-coll` in the same DB.
Takes an options map: Arguments:
-- query options
:drop-target? Boolean drop tne target collection if it exists. Default: false
:rename-collection-options A RenameCollectionOptions for configuring directly. If specified, - `db` is a MongoDatabase
any other query options will be applied to it" - `coll` is a collection name
- `new-coll` is the target collection name
- `opts` (optional), a map of:
- `:drop-target?` Boolean drop tne target collection if it exists. Default: false
- `:rename-collection-options` A RenameCollectionOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it"
([^MongoDatabase db coll new-coll] ([^MongoDatabase db coll new-coll]
(rename db coll new-coll {})) (rename db coll new-coll {}))
([^MongoDatabase db coll new-coll opts] ([^MongoDatabase db coll new-coll opts]
@ -651,18 +641,17 @@
(defn create-index (defn create-index
"Creates an index "Creates an index
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`keys` is a document representing index keys, e.g. {:a 1}
Takes an options map: - `db` is a MongoDatabase
-- query options - `coll` is a collection name
:name - `keys` is a document representing index keys, e.g. {:a 1}
:sparse? - `opts` (optional), a map of:
:unique? - `:name`
- `:sparse?`
:index-options An IndexOptions for configuring directly. If specified, - `:unique?`
any other query options will be applied to it" - `:index-options` An IndexOptions for configuring directly. If specified,
any other [preceding] query options will be applied to it"
([^MongoDatabase db coll keys] ([^MongoDatabase db coll keys]
(create-index db coll keys {})) (create-index db coll keys {}))
([^MongoDatabase db coll keys opts] ([^MongoDatabase db coll keys opts]
@ -671,15 +660,15 @@
(defn create-indexes (defn create-indexes
"Creates many indexes. "Creates many indexes.
`db` is a MongoDatabase Arguments:
`coll` is a collection name
`indexes` is a collection of maps with the following attributes:
-- required - `db` is a MongoDatabase
:keys a document representing index keys, e.g. {:a 1} - `coll` is a collection name
- `indexes` is a collection of maps with the following keys:
-- optional - `:keys` (mandatory) a document representing index keys, e.g. {:a 1}
any attributes available in `->IndexOptions`" - `:name`
- `:sparse?`
- `:unique?`"
([^MongoDatabase db coll indexes] ([^MongoDatabase db coll indexes]
(create-indexes db coll indexes {})) (create-indexes db coll indexes {}))
([^MongoDatabase db coll indexes opts] ([^MongoDatabase db coll indexes opts]

View file

@ -7,7 +7,7 @@
(com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions UpdateOptions ReplaceOptions IndexOptions CreateCollectionOptions RenameCollectionOptions) (com.mongodb.client.model InsertOneOptions InsertManyOptions DeleteOptions FindOneAndUpdateOptions ReturnDocument FindOneAndReplaceOptions CountOptions UpdateOptions ReplaceOptions IndexOptions CreateCollectionOptions RenameCollectionOptions)
(java.time ZoneId LocalDate LocalTime LocalDateTime) (java.time ZoneId LocalDate LocalTime LocalDateTime)
(java.util Date UUID) (java.util Date UUID)
(com.mongodb.client MongoDatabase))) (com.mongodb.client FindIterable)))
;;; Unit ;;; Unit
@ -204,7 +204,7 @@
(let [db (new-db @client) (let [db (new-db @client)
doc {:hello "world"} doc {:hello "world"}
_ (mc/insert-one db "test" doc) _ (mc/insert-one db "test" doc)
res (mc/find-maps db "test" {})] res (mc/find db "test" {})]
(is (= 1 (count res))) (is (= 1 (count res)))
(is (= doc (select-keys (first res) [:hello]))))) (is (= doc (select-keys (first res) [:hello])))))
@ -225,7 +225,7 @@
:localdatetime (LocalDateTime/now) :localdatetime (LocalDateTime/now)
:localtime (LocalTime/now)} :localtime (LocalTime/now)}
_ (mc/insert-one db "test" doc) _ (mc/insert-one db "test" doc)
res (mc/find-one-as-map db "test" {} {:projection {:_id 0}})] res (mc/find-one db "test" {} {:projection {:_id 0}})]
(is (= {:nil nil (is (= {:nil nil
:string "string" :string "string"
:int 1 :int 1
@ -245,7 +245,7 @@
(testing "basic insertions" (testing "basic insertions"
(let [db (new-db @client) (let [db (new-db @client)
_ (mc/insert-many db "test" [{:id 1} {:id 2}]) _ (mc/insert-many db "test" [{:id 1} {:id 2}])
res (mc/find-maps db "test" {})] res (mc/find db "test" {})]
(is (= 2 (count res))) (is (= 2 (count res)))
(is (= [1 2] (map :id res))))) (is (= [1 2] (map :id res)))))
@ -279,58 +279,74 @@
(is (= 2 (.getDeletedCount (mc/delete-many db "test" {:v 1})))) (is (= 2 (.getDeletedCount (mc/delete-many db "test" {:v 1}))))
(is (= 0 (.getDeletedCount (mc/delete-many db "test" {:v 1}))))))) (is (= 0 (.getDeletedCount (mc/delete-many db "test" {:v 1})))))))
(deftest ^:integration test-find-maps (deftest ^:integration test-find
(let [db (new-db @client) (let [db (new-db @client)
_ (mc/insert-many db "test" [{:id 1 :a 1 :v 2} {:id 2 :a 1 :v 3} {:id 3 :v 1}])] _ (mc/insert-many db "test" [{:id 1 :a 1 :v 2} {:id 2 :a 1 :v 3} {:id 3 :v 1}])]
(testing "query" (testing "query"
(are [ids q] (= ids (map :id (mc/find-maps db "test" q))) (are [ids q] (= ids (map :id (mc/find db "test" q)))
[1 2 3] {} [1 2 3] {}
[1] {:id 1} [1] {:id 1}
[1 2] {:a {:$exists true}} [1 2] {:a {:$exists true}}
[2] {:v {:$gt 2}})) [2] {:v {:$gt 2}}))
(testing "sort" (testing "sort"
(are [ids s] (= ids (map :id (mc/find-maps db "test" {} {:sort s}))) (are [ids s] (= ids (map :id (mc/find db "test" {} {:sort s})))
[1 2 3] {} [1 2 3] {}
[3 1 2] {:v 1} [3 1 2] {:v 1}
[2 1 3] {:v -1})) [2 1 3] {:v -1}))
(testing "skip"
(are [cnt n] (= cnt (count (mc/find db "test" {} {:skip n})))
3 0
2 1
1 2
0 3))
(testing "limit" (testing "limit"
(are [cnt n] (= cnt (count (mc/find-maps db "test" {} {:limit n}))) (are [cnt n] (= cnt (count (mc/find db "test" {} {:limit n})))
1 1 1 1
2 2 2 2
3 3 3 3
3 4)) 3 4))
(testing "projection" (testing "projection"
(are [ks p] (= ks (keys (first (mc/find-maps db "test" {} {:projection p})))) (are [ks p] (= ks (keys (first (mc/find db "test" {} {:projection p}))))
[:_id :id :a :v] {} [:_id :id :a :v] {}
[:_id :a] {:a 1} [:_id :a] {:a 1}
[:id :a :v] {:_id 0})))) [:id :a :v] {:_id 0}))
(deftest ^:integration test-find-one-as-map (testing "raw"
(is (instance? FindIterable (mc/find db "test" {} {:raw? true}))))
(testing "keywordize"
(is (= [{"id" 1}] (mc/find db "test" {} {:keywordize? false :projection {:_id 0 :id 1} :limit 1}))))))
(deftest ^:integration test-find-one
(let [db (new-db @client) (let [db (new-db @client)
_ (mc/insert-many db "test" [{:id 1 :a 1 :v 2} {:id 2 :a 1 :v 3} {:id 3 :v 1}])] _ (mc/insert-many db "test" [{:id 1 :a 1 :v 2} {:id 2 :a 1 :v 3} {:id 3 :v 1}])]
(testing "query" (testing "query"
(are [id q] (= id (:id (mc/find-one-as-map db "test" q))) (are [id q] (= id (:id (mc/find-one db "test" q)))
1 {} 1 {}
2 {:id 2} 2 {:id 2}
1 {:a {:$exists true}} 1 {:a {:$exists true}}
2 {:v {:$gt 2}})) 2 {:v {:$gt 2}}))
(testing "sort" (testing "sort"
(are [id s] (= id (:id (mc/find-one-as-map db "test" {} {:sort s}))) (are [id s] (= id (:id (mc/find-one db "test" {} {:sort s})))
1 {} 1 {}
3 {:v 1} 3 {:v 1}
2 {:v -1})) 2 {:v -1}))
(testing "projection" (testing "projection"
(are [ks p] (= ks (keys (mc/find-one-as-map db "test" {} {:projection p}))) (are [ks p] (= ks (keys (mc/find-one db "test" {} {:projection p})))
[:_id :id :a :v] {} [:_id :id :a :v] {}
[:_id :a] {:a 1} [:_id :a] {:a 1}
[:id :a :v] {:_id 0})))) [:id :a :v] {:_id 0}))
(testing "keywordize"
(is (= {"id" 1} (mc/find-one db "test" {} {:keywordize? false :projection {:_id 0 :id 1}}))))))
(deftest ^:integration test-count-documents (deftest ^:integration test-count-documents
(let [db (new-db @client) (let [db (new-db @client)