达托米:'Not in collection'查询不起作用



我试图从数据库中获取所有用户,除了那些与一组UID相关的用户。我已经编写了这个查询,但是当uid列表有多个元素时,由于某种原因,"not"子句不起作用,它返回给我所有注册用户。

(d/q '[:find (pull ?e [*])
:in $ [?uids ...]
:where [?e :user/id ?uid]
(not [?e :user/id ?uids])]
db ["user-uid-1" "user-uid-2" "user-uid-3"])

当UID的列表包含单个元素时,查询正常工作(它返回所有用户,除了具有指定UID的用户)。

你知道哪里出了问题吗?

使用[?uids ...]的行为类似于SELECT * FROM user WHERE id != uid1 UNION SELECT * FROM user WHERE id != uid2,而不是预期的SELECT * FROM user WHERE id NOT IN (uids)

例如,在下面的示例查询中,试图获取除苹果或梨以外的所有水果

(d/q
'[:find ?id ?fruit ?fruits
:in $ [?fruits ...]
:where
[?id :fruit ?fruit]
(not [?id :fruit ?fruits])]
[[1 :fruit :apple]
[2 :fruit :orange]
[3 :fruit :pear]]
[:apple :pear])
; => #{[3 :pear :apple] [2 :orange :pear] [1 :apple :pear] [2 :orange :apple]}

我们看到查询对列表中的每个水果都运行。:pear[2 :orange :pear] [1 :apple :pear],:apple[3 :pear :apple] [2 :orange :apple]

为了找到不在集合中的所有项目,您需要将集合设置为集合并将其发送到标量绑定中,如

(d/q
'[:find ?id ?fruit ?fruits
:in $ ?fruits
:where
[?id :fruit ?fruit]
(not [(?fruits ?fruit)])]
[[1 :fruit :apple]
[2 :fruit :orange]
[3 :fruit :pear]]
#{:apple :pear})
; => #{[2 :orange #{:apple :pear}]}

在您的情况下,您将希望重写查询如下

(d/q '[:find (pull ?e [*])
:in $ ?uids
:where [?e :user/id ?uid]
(not [(?uids ?uid)]
db #{"user-uid-1" "user-uid-2" "user-uid-3"})

最新更新