Clojure 为什么monger只更新一条记录而不是列表中的所有记录

Clojure 为什么monger只更新一条记录而不是列表中的所有记录,clojure,monger,Clojure,Monger,我有一个函数,它接收条目列表并使用monger将其保存到mongo。 奇怪的是,除非我指定multi:true,否则只更新一条记录,而忽略其余记录。 我不明白为什么monger需要使用multi标志来保存对mongodb的所有更新 (defn update-entries [entries] (let [conn (mg/connect) db (mg/get-db conn "database")] (for [e entries] (mc/update

我有一个函数,它接收条目列表并使用monger将其保存到mongo。 奇怪的是,除非我指定
multi:true
,否则只更新一条记录,而忽略其余记录。 我不明白为什么monger需要使用multi标志来保存对mongodb的所有更新

(defn update-entries
   [entries]
   (let [conn (mg/connect)
         db (mg/get-db conn "database")]
     (for [e entries] (mc/update db "posts" {"id" (:id e)} {$set {:data (:data e)}} {:multi true}))))

multi标志对于多次更新是必需的,因为mongo本身就是这样使用的。请查看有关的文档。当然,这是MongoShell,但大多数驱动程序在操作语义方面都会遵循它

请注意,如果
“id”
是唯一的,则一次更新一条记录,因此将
:multi
设置为
true
应该无关紧要

但是,您的代码还有另一个问题

您使用一个理解,它反过来惰性地迭代一个集合
mc/update
,即在您强制实现
for
返回的集合之前,不会调用
mc/update

由于
mc/update
是针对其副作用(更新数据库中的记录)而进行的调用,因此使用将更合适,除非您需要结果

如果是这种情况,请在
doall
中包装
for
,以强制实现:

(doall 
    (for [e entries] 
         (mc/update db "posts" {"id" (:id e)} {$set {:data (:data e)}} {:multi true})))))

我最初使用的是
doseq
,但因为我没有看到更新,所以我改为
for
以查看输出。我理解你的解释,你自己也说过,因为我匹配的是“id”,所以设置multi:true应该不重要——不过这是我试图理解的问题。@SeymourCakes如果你需要结果,你可以使用
doall
而不是
doseq
。无论如何,您需要以某种方式强制实现序列。