如何在 Ecto MongoDB 中执行 $push $pull $set 等原子操作
How to do atomic operations like $push $pull $set etc. in Ecto MongoDB
我正在使用 mongodb_ecto,我想知道如何在深度嵌套的字段上执行 $push 或 $pull 等操作?目前我写回了整个文档,有时由于竞争条件导致错误数据出现在数据库中。
好的,我有点明白了。不要为此使用 Ecto。在某些情况下,您需要 MongoDB positional operator,这只能通过 Mongo-适配器直接完成。现在来看一些用法示例:
我有一份包含选项列表的文档。选项有一个 ID、一个标签和投票支持该选项的用户 ID 列表。
BTW 生成一个 ObjectID(直接与 MongoDB-Adapter 对话需要)使用这个:
id = "584a5b9419d51d724d146e3f" # string form
value = (for <<hex::16 <- id>>, into: <<>>, do: <<String.to_integer(<<hex::16>>, 16)::8>>)
object_id = %BSON.ObjectId{value: value}
现在举一些例子:
# update label of option
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id, "options.id" => option_id}, # query
%{"$set" => %{"data.options.$.label" => new_label}} # update
)
# add new option to poll
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id},
%{"$addToSet" => %{"options" => %{label: label, id: random_new_id, votes: []}}}
)
# add user_id to option
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id, "options.id" => option_id},
%{"$addToSet" => %{"options.$.votes" => user_id}}
)
# remove user_id form option
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id, "options.id" => option_id},
%{"$pull" => %{"data.options.$.votes" => user_id}}
)
我正在使用 mongodb_ecto,我想知道如何在深度嵌套的字段上执行 $push 或 $pull 等操作?目前我写回了整个文档,有时由于竞争条件导致错误数据出现在数据库中。
好的,我有点明白了。不要为此使用 Ecto。在某些情况下,您需要 MongoDB positional operator,这只能通过 Mongo-适配器直接完成。现在来看一些用法示例:
我有一份包含选项列表的文档。选项有一个 ID、一个标签和投票支持该选项的用户 ID 列表。
BTW 生成一个 ObjectID(直接与 MongoDB-Adapter 对话需要)使用这个:
id = "584a5b9419d51d724d146e3f" # string form
value = (for <<hex::16 <- id>>, into: <<>>, do: <<String.to_integer(<<hex::16>>, 16)::8>>)
object_id = %BSON.ObjectId{value: value}
现在举一些例子:
# update label of option
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id, "options.id" => option_id}, # query
%{"$set" => %{"data.options.$.label" => new_label}} # update
)
# add new option to poll
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id},
%{"$addToSet" => %{"options" => %{label: label, id: random_new_id, votes: []}}}
)
# add user_id to option
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id, "options.id" => option_id},
%{"$addToSet" => %{"options.$.votes" => user_id}}
)
# remove user_id form option
Mongo.update_one(Repo.Pool, "polls",
%{"_id" => document_id, "options.id" => option_id},
%{"$pull" => %{"data.options.$.votes" => user_id}}
)