Skip to content

Instantly share code, notes, and snippets.

@refset
Last active January 31, 2022 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save refset/93135adcbf41fccab9b641638ab10997 to your computer and use it in GitHub Desktop.
Save refset/93135adcbf41fccab9b641638ab10997 to your computer and use it in GitHub Desktop.
multi-att query predicate and wildcard attributes lookups
(defn multi-att [db e a v]
;; unsupported edge case if a stored/searched value is actually the symbol `_`
;; if provided `a` is `_` then lookup defaults to :xt/id
;; use `attribute-stats` as an input relation to `a` for wildcard attribute lookups
(let [a (if (= a '_) :xt/id a)]
(if (and (= e '_) (= v '_))
(let [evs (xt/q db {:find '[e v]
:where [['e a 'v]]})]
(for [[e v] evs] [e a v]))
(if (= e '_)
(let [es (xt/q db {:find '[e]
:where [['e a v]]})]
(for [[e] es] [e a v]))
(if (= v '_)
(let [vs (xt/q db {:find '[v]
:where [[e a 'v]]})]
(for [[v] vs] [e a v]))
(when (some? (ffirst (xt/q db {:find '[t]
:where [[e a v]
'[(identity true) t]]})))
[[e a v]]))))))
(let [node (xt/start-node {})]
(xt/await-tx node (xt/submit-tx node [[::xt/put {:xt/id :foo2 :a :bar :b :baz :c :qaz}]
[::xt/put {:xt/id :foo :a :bar :b :baz :c :qaz :z :bar}]]))
(with-open [db (xt/open-db node)]
(xt/q db '{:find [e* a* v*]
:in [[e ...] [a ...] [v ...]]
:where [[(dev/multi-att $ e a v) [[e* a* v*]]]]}
#{:foo '_}
(keys (xt/attribute-stats node))
#{:bar '_})))
;; => #{[:foo :b :baz] [:foo :a :bar] [:foo :c :qaz] [:foo2 :a :bar] [:foo2 :b :baz] [:foo :crux.db/id :foo] [:foo2 :c :qaz] [:foo2 :crux.db/id :foo2] [:foo :z :bar]}
;; (returns everything)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment