Tested on datascript 1.3.0
datoms:
[{:db/id -1 :name "Smith" :firstname "Oliver" :age 20}
{:db/id -2 :name "Jones" :firstname "Oliver" :age 20}
{:db/id -3 :name "Smith" :firstname "Amelia" :age 16}
{:db/id -4 :name "Jones" :firstname "Amelia" :age 16}]
tried to query with logical and
predicates below who are named Smith and aged older than 18 years, why did it return the unfiltered whole set?
'[:find ?firstname ?name
:where
[?p :name ?name]
[?p :firstname ?firstname]
[?p :age ?age]
[(and (= ?name "Smith") (> ?age 18))]]
;;; wrong result: #{[Oliver Smith] [Oliver Jones] [Amelia Smith] [Amelia Jones]}
then changed to query with discrete predicates and got the satisfied result as expected.
'[:find ?firstname ?name
:where
[?p :name ?name]
[?p :firstname ?firstname]
[?p :age ?age]
[(= ?name "Smith")]
[(> ?age 18)]]
;;; correct result: #{[Oliver Smith]}
Do datomic
and datascript
or datalog
in general only support data patterns scattered to discrete clauses? Are conventional logical operations and
etc. incompatible here?
According to the manual you cannot use an and-clause
just like that. The only way you can use an and-clause
is when it is inside an or-clause
:
Inside the or clause, you may use an and clause to specify conjunction. This clause is not available outside of an or clause, since conjunction is the default in other clauses.