Tested on datomic-free 0.9.5697, clojure 1.10.3 and openjdk 17.01.
(require '[datomic.api :as d])
(def uri "datomic:mem://test")
(d/create-database uri)
(def conn (d/connect uri))
(def db (-> conn d/db delay))
(def schema [{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}])
(d/transact conn schema)
(def datoms [{:person/name "Oliver Smith"}])
(d/transact conn datoms)
(def query '[:find ?name
:where
[_ :person/name ?name]])
(-> (d/q query @db) println) ; ok => #{[Oliver Smith]}
(def query '[:find ?name
:where
[(fulltext $ :person/name "Smith") [[_ ?name]]]])
(-> (d/q query @db) println) ; nok => expected: #{[Oliver Smith]}, actual: #{}
Why did the above fulltext search return empty?
As @Steffan Westcott has pointed out, we need add :db/fulltext true
to the desired attribute in the schema thus enable the feature of fulltext search on it. Now it works after wasting hours to find out myself. Thanks a ton, Steffan.
According to the doc,
:db/fulltext specifies a boolean value indicating that an eventually consistent fulltext search index should be generated for the attribute. Defaults to false.
So the said schema is corrected below,
(def schema [{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true}
])
We can demonstrate that fulltext search on Datomic works by another example below - find who are "Smith" and "music" is one of their hobbies.
test.clj
(require '[datomic.api :as d])
(def uri "datomic:mem://test")
(d/create-database uri)
(def conn (d/connect uri))
(def db (-> conn d/db delay))
(def schema [{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true}
{:db/ident :person/hobby
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true}
])
(d/transact conn schema)
(def datoms [{:person/name "Oliver Smith" :person/hobby "reading, sports and music"}
{:person/name "Amelia Smith" :person/hobby "reading, music and dance"}
{:person/name "George Smith" :person/hobby "reading and sports"}
{:person/name "Amelia Jones" :person/hobby "reading, music and dance"}
])
(d/transact conn datoms)
(def query '[:find ?name ?hobby
:where
[(fulltext $ :person/name "Smith") [[?p ?name]]]
[(fulltext $ :person/hobby "music") [[?p ?hobby]]]
])
(-> (d/q query @db) println) ; ok
run it to get the expected result below,
$ clj -Sdeps '{:deps {com.datomic/datomic-free {:mvn/version "0.9.5697"}}}' -M test.clj
stdout: #{[Oliver Smith reading, sports and music]
[Amelia Smith reading, music and dance]}