为什么在 Datomic 上全文搜索失败?
Why the fulltext search failed on Datomic?
在 datomic-free 0.9.5697、clojure 1.10.3 和 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: #{}
为什么上面fulltext搜索return为空?
正如@Steffan Westcott 指出的那样,我们需要将 :db/fulltext true
添加到模式中所需的属性,从而启用对其进行全文搜索的功能。现在,在浪费数小时来了解自己之后,它开始起作用了。非常感谢,Steffan。
根据doc,
:db/fulltext specifies a boolean value indicating that an eventually
consistent fulltext search index should be generated for the
attribute. Defaults to false.
所以在下面更正了所述架构,
(def schema [{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true}
])
我们可以通过下面的另一个例子来证明 Datomic 上的全文搜索是有效的——找到谁是“Smith”,“music”是他们的爱好之一。
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
运行 得到下面的预期结果,
$ 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]}
在 datomic-free 0.9.5697、clojure 1.10.3 和 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: #{}
为什么上面fulltext搜索return为空?
正如@Steffan Westcott 指出的那样,我们需要将 :db/fulltext true
添加到模式中所需的属性,从而启用对其进行全文搜索的功能。现在,在浪费数小时来了解自己之后,它开始起作用了。非常感谢,Steffan。
根据doc,
:db/fulltext specifies a boolean value indicating that an eventually consistent fulltext search index should be generated for the attribute. Defaults to false.
所以在下面更正了所述架构,
(def schema [{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true}
])
我们可以通过下面的另一个例子来证明 Datomic 上的全文搜索是有效的——找到谁是“Smith”,“music”是他们的爱好之一。
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
运行 得到下面的预期结果,
$ 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]}