Cómo filtrar vectores de mapas por múltiples claves en Clojure

Supongamos que tenemos una estructura de datos como esta:

(def data
     (atom [{:id 1 :first-name "John1" :last-name "Dow1" :age "14"}
            {:id 2 :first-name "John2" :last-name "Dow2" :age "54"}
            {:id 3 :first-name "John3" :last-name "Dow3" :age "34"}
            {:id 4 :first-name "John4" :last-name "Dow4" :age "12"}
            {:id 5 :first-name "John5" :last-name "Dow5" :age "24"}]))

Aprendí a filtrarlo por una tecla, por ejemplo:

(defn my-filter
  [str-input]
  (filter #(re-find (->> (str str-input)
                         (lower-case)
                         (re-pattern))
                         (lower-case (:first-name %)))
            @data))

> (my-filter "John1")
> ({:last-name "Dow1", :age "14", :first-name "John1", :id 1})

Pero ahora estoy un poco confundido sobre cómo filtrar datos por:first-name, :last-name y:age ¿manera simple?

Actualizar: S, Orry por no ser lo suficientemente claro como para explicar cuál es el problema ... En realidad, quiero todas las claves:first-name, :last-name y:age para participar en la función de filtro, de modo que, sistr-input no coincide:first-name's val, compruebe si coincide:last-nameEs val y así sucesivamente.

Actualización 2: Después de intentarsome-fn, every-pred ytransducers, No obtuve lo que necesito, p. regex en predicados de filtro, supongo que es una falta de conocimiento por ahora. Entonces, terminé con esta función que funciona bien, pero el código es feo y está duplicado. ¿Cómo puedo deshacerme de la duplicación de código?

(defn my-filter [str-input]
  (let [firstname (filter #(re-find (->> (str str-input)
                                         (upper-case)
                                         (re-pattern))
                                    (upper-case (:first-name %)))
                     @data)
        lastname (filter #(re-find (->> (str str-input)
                                        (upper-case)
                                        (re-pattern))
                                   (upper-case (:last-name %)))
                    @data)
        age (filter #(re-find (->> (str str-input)
                                   (upper-case)
                                   (re-pattern))
                              (upper-case (:age %)))
               @data)]
    (if-not (empty? firstname)
      firstname
      (if-not (empty? lastname)
        lastname
        (if-not (empty? age)
          age)))))

Respuestas a la pregunta(2)

Su respuesta a la pregunta