forked from threatgrid/clj-momo
/
query.clj
69 lines (60 loc) · 1.88 KB
/
query.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
(ns clj-momo.lib.es.query
(:require [clojure.string :as str]
[schema.core :as s]
[clj-momo.lib.es.schemas :refer :all]
))
(s/defn bool :- BoolQuery
"Boolean Query"
[opts :- BoolQueryParams]
{:bool opts})
(defn filtered
"Filtered query"
[opts]
{:filtered opts})
(defn nested
"Nested document query"
[opts]
{:nested opts})
(defn term
"Term Query"
([key values] (term key values nil))
([key values opts]
(merge { (if (coll? values) :terms :term) (hash-map key values) }
opts)))
(defn terms
"Terms Query"
([key values] (terms key values nil))
([key values opts]
(term key values opts)))
(defn nested-terms [filters]
"make nested terms from a filter:
[[[:observable :type] ip] [[:observable :value] 42.42.42.1]]
->
[{:terms {observable.type [ip]}} {:terms {observable.value [42.42.42.1]}}]
we force all values to lowercase, since our indexing does the same for all terms."
(vec (map (fn [[k v]]
(terms (->> k
(map name)
(str/join "."))
(map #(if (string? %)
(str/lower-case %)
%)
(if (coll? v) v [v]))))
filters)))
(defn prepare-terms [filter-map]
(let [terms (map (fn [[k v]]
(let [t-key (if (sequential? k) k [k])]
[t-key v]))
filter-map)]
(nested-terms terms)))
(defn filter-map->terms-query
"transforms a filter map to en ES terms query"
([filter-map]
(filter-map->terms-query filter-map nil))
([filter-map query]
(let [filter-terms (prepare-terms filter-map)]
(bool {:filter
(cond
(every? empty? [query filter-map]) [{:match_all {}}]
(empty? query) filter-terms
:else (conj filter-terms query))}))))