如何在Elixir中使用mongodb v0.4同时建立两个MongoDB连接?
如何在Elixir中用mongodb v0.4连接两个MongoDB并实现数据传输
嘿,这个需求其实很容易实现——核心就是给每个MongoDB连接分配唯一的标识名,让Supervisor同时管理两个独立的连接进程,之后你就可以分别操作这两个库来完成数据传输了。
第一步:修改Supervisor配置,添加第二个连接
你只需要在children列表里新增一个Mongo worker,给它设置不同的name、database(如果需要的话)和seeds参数就行。记得每个连接的name必须唯一,这样后续操作时才能区分它们。
修改后的完整Supervisor启动代码如下:
children = [ # 第一个MongoDB连接:对应原有的transit库 worker(Mongo, [ name: :mongo_transit, database: "transit", seeds: ["localhost:27017"], pool: DBConnection.Pool ]), # 第二个MongoDB连接:替换成你的目标库信息 worker(Mongo, [ name: :mongo_target, database: "your_target_db", seeds: ["localhost:27017"], # 如果是不同服务器就改这里的地址 pool: DBConnection.Pool ]) ] opts = [strategy: :one_for_one, name: HugoEtl.Supervisor] Supervisor.start_link(children, opts)
第二步:操作时指定对应的连接
在进行数据库操作(查询、插入、更新等)时,你需要通过:pool参数指定要使用的连接名称,这样mongodb模块就知道该用哪个连接进程了。
举几个简单的例子:
- 从第一个库读取数据:
# 从transit库的"source_collection"中查询数据 cursor = Mongo.find(:mongo_transit, "source_collection", %{}, pool: :mongo_transit)
- 插入数据到第二个库:
# 把文档插入到目标库的"target_collection" Mongo.insert_one(:mongo_target, "target_collection", %{name: "test", value: 123}, pool: :mongo_target)
第三步:实现两个库之间的数据传输
你可以封装一个简单的函数来处理数据传输,比如批量读取源库的数据,然后写入目标库。考虑到数据量可能较大,建议用游标遍历的方式,避免一次性加载所有数据到内存:
defmodule HugoEtl.DataTransfer do def transfer_collection(source_conn, source_coll, target_conn, target_coll) do # 从源库获取游标 cursor = Mongo.find(source_conn, source_coll, %{}, pool: source_conn) # 遍历游标,逐个插入到目标库 Enum.each(cursor, fn doc -> # 注意:如果需要转换数据格式,可以在这里处理doc case Mongo.insert_one(target_conn, target_coll, doc, pool: target_conn) do {:ok, _result} -> :ok {:error, reason} -> IO.puts("插入失败:#{inspect(reason)}") end end) end end # 调用示例:从transit的"users"传输到目标库的"migrated_users" HugoEtl.DataTransfer.transfer_collection(:mongo_transit, "users", :mongo_target, "migrated_users")
如果数据量很大,你还可以用Stream配合批量插入来优化性能,比如每100条数据批量插入一次,减少IO开销。
内容的提问来源于stack exchange,提问作者Ludovic Zenohate Lagouardette
相关产品推荐
相关产品推荐

