I want to use some “operators” that are used with MongoDB.
I’m using this library:
and I include this code:
(:require
[fourth.logging :as log]
[overtone.at-at :as at]
[clojure.java.io :as io]
[mongo-driver-3.client :as mcl]
[mongo-driver-3.collection :as mc]
[mongo-driver-3.operator :refer [$gt]]
[java-time :as jt])
Assume params
is some JSON sent in from the outside world, via some API call. This JSON contains fields or sub documents that correspond to the main options that I need to work with to get what I need from MongoDB:
find – a map to match documents in the database
limit
skip
sort
projection – what fields to return
I use a multi method for this, in the default version I hardcode some values, and this works:
(mc/find db "ai" (:filter params) {
:keywordize? true
:realise-fn (partial into [])
:projection {:_id 0}
:sort {:created-at -1}
}))
But I would like to use this operator:
$gt
which is for “greater than”.
To make my life easy I was going to allow the API to hardcode the field and value for this comparison, and only allow one use of $gt per API call.
So I tried to do this:
(defn query-format
[params]
(let [
greater-than-field (:greater-than-field params)
greater-than-value (:greater-than-value params)
filter (if (and
greater-than-field
greater-than-value)
(merge filter {
greater-than-field { $gt greater-than-value }
})
filter)
params (assoc params :filter filter)
]
(query params)))
Which I was hoping would be easy.
It does compile, so the compiler recognizes the $gt symbol in this context.
But when I run this and then try to call this I get:
java.lang.ClassCastException: class clojure.core$filter cannot be cast to class org.bson.conversions.Bson
I’m not sure what this means, but I assume something is unhappy when it looks in the filter
var and sees another var?
Is there a correct way to do this?
The documentation on this MongoDB driver repo says I could also do this:
“gt”
And I tried that but I got the same error. So it make not be about the symbol $gt. Instead it is something about filter
not converting correctly. Not sure how to make this work.