Last active
October 22, 2018 15:55
-
-
Save bostonaholic/30e31f4620804632d3c8 to your computer and use it in GitHub Desktop.
Showing datomic or-join searches
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require '[clojure.test :refer [is]]) | |
(require '[datomic.api :as d]) | |
(def url "datomic:mem://localhost:4334/test") | |
(d/create-database url) | |
(def conn (d/connect url)) | |
(def schema [{:db/id #db/id[:db.part/db] | |
:db/ident :person/name | |
:db/valueType :db.type/string | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id[:db.part/db] | |
:db/ident :person/address | |
:db/valueType :db.type/ref | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id[:db.part/db] | |
:db/ident :address/street | |
:db/valueType :db.type/string | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id[:db.part/db] | |
:db/ident :address/zip | |
:db/valueType :db.type/string | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db}]) | |
(d/transact conn schema) | |
(def alice {:db/id #db/id[:db.part/user -1] | |
:person/name "Alice" | |
:person/address {:db/id #db/id[:db.part/user -10] | |
:address/street "123 Fake St." | |
:address/zip "12345"}}) | |
(def bob {:db/id #db/id[:db.part/user -2] | |
:person/name "Bob" | |
:person/address {:db/id #db/id[:db.part/user -20] | |
:address/street "456 Fake St." | |
:address/zip "67890"}}) | |
(def charles {:db/id #db/id[:db.part/user -3] | |
:person/name "Charles" | |
:person/address {:db/id #db/id[:db.part/user -30] | |
:address/street "123 Bob St." | |
:address/zip "67890"}}) | |
(def danielle {:db/id #db/id[:db.part/user -4] | |
:person/name "Danielle" | |
:person/address {:db/id #db/id[:db.part/user -40] | |
:address/street "123 Something St." | |
:address/zip "76543"}}) | |
(d/transact conn [alice bob charles danielle]) | |
(defn search [db query zips] | |
(d/q '[:find [(pull ?person [* {:person/address [*]}]) ...] | |
:in $ ?pattern [?zip ...] | |
:where | |
(or-join [?person ?pattern ?zip] | |
(and [?person :person/address ?address] | |
[?address :address/zip ?zip]) | |
(and [?person :person/name ?name] | |
[(re-find ?pattern ?name)]) | |
(and [?person :person/address ?address] | |
[?address :address/street ?street] | |
[(re-find ?pattern ?street)]))] | |
db | |
(re-pattern (str "(?i).*" query ".*")) | |
zips)) | |
(defn compare-names [expected actual] | |
(is (= (set (map :person/name expected)) | |
(set (map :person/name actual))))) | |
(compare-names (list bob charles danielle) | |
(search (d/db conn) "bob" ["67890" "76543"])) | |
(comment | |
"Expected:" | |
"bob, becuase his name matches the query." | |
"charles, because his street matches the query." | |
"danielle, because her zip is in the list of zip codes.") | |
(compare-names (list danielle) | |
(search (d/db conn) "foo" ["76543"])) | |
(comment | |
"Expected:" | |
"danielle, because her zip is in the list of zip codes.") | |
(compare-names (list alice) | |
(search (d/db conn) "alice" [])) | |
(comment | |
"Expected:" | |
"alice, because her name matches the query.") | |
(compare-names (list alice) | |
(search (d/db conn) "alice" [""])) | |
(comment "This works!?") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment