When using congomongo library to access MongoDB in Clojure, it is sometimes required to remove a collection of items. As the example on GitHub page shows only how to remove one item, I have pasted the code here.
Setup test data
To setup test data, we would use 100 items in :points collection.
(use 'somnium.congomongo) (mass-insert! :points (for [x (range 0 10) y (range 0 10)] {:x x :y y})) (count (fetch :points)) ;=> 100
Please note, that I am not writing any code specific to establishing a connection here. For more information on using congomongo library, please visit congomongo github site.
The obvious way
The most obvious way to do so, would be to pass a list objects to destroy! function. Sadly, it won't work:
user=> (destroy! :points (fetch :points)) ;=> ClassCastException clojure.lang.LazySeq cannot be ;=> cast to com.mongodb.DBObject ;=> somnium.congomongo/destroy! (congomongo.clj:419)
Using for loop
We can also invoke destroy!
a hundred times:
(count (fetch :points)) ;=> 100 (for [p (fetch :points)] (destroy! :points p)) (count (fetch :points)) ;=> 0
It will work, but it is not optimal.
Using where clause
The best way to remove a collection of items in MongoDB using congomongo, it would be to use where clause for a destroy!
function:
(count (fetch :points)) ;=> 100 (destroy! :points {:x {:$gt 4}}) (count (fetch :points)) ;=> 50
It is also possible to refer MongoDB items by their ids in where clause:
(count (fetch :points)) ;=> 100 (destroy! :points {:_id {:$in (map :_id (fetch :points))}}) (count (fetch :points)) ;=> 0