Filtering a data structure using regex predicates
First up, notice that you're creating 3 leted names by using exactly the same expression but replacing one key lookup function. This is a prime candidate for deduplication by making a local function. 

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


Next we can notice that the remainder is just doing the same "return this if it's not empty" logic with each of the three keys in sequence. some returns the first non-falsy result of a function on a sequence so by adding a seq to the seek function we can turn empty filter sequences into nils we can combine the two and get the logic we want. I used letfn this time because we're only leting fns, might as well.

(defn my-filter [str-input]
  (letfn[(seek [k]
               (seq (filter #(re-find (-&gt;&gt; (str str-input)
                                         (upper-case)
                                         (re-pattern))
                                    (upper-case (k %)))
                     @data)))]
    (some seek [:first-name :last-name :age])))