mongodb-erlang文档阅读+源码解析

本文详细介绍了mongodb-erlang客户端,包括连接MongoDB、写入、读取、更新、创建索引等操作。探讨了连接参数如login、password和w_mode的作用,并解析了数据的编码解码过程。此外,文章还深入源码,分析了mc_worker_api和mc_worker的工作原理,以及数据包的发送与接收机制。
摘要由CSDN通过智能技术生成

mongodb-erlang 是一个非官方的MongoDB客户端,提供了Erlang语言版本的MongoDB驱动。本文旨在通过对其文档和源码的分析探索其使用方法,解析其工作方式。

我们假定读者已经有了如下的知识储备:

  • Erlang语言的语法和OTP的的基本使用方法
  • MongoDB的基本用法
  • Erlang进程池管理项目poolboy的基本用法

文档解析

我们从文档可以得知,该项目有两个api模块:mc_worker_api.erlmongo_api.erlmc_worker_api.erl会建立单独的连接与MongoDB进行交互,mongo_api.erl则会建立连接池,管理与MongoDB的多个连接。

文档还提到了,如果要在官方提供的mongos(MongoDB分片集群路由)和通过mongo_api.erl连接shard(分片)之间进行选择,建议使用mongos + mc_worker_api.erl的组合。

连接

使用mc_worker_api:connect/1连接MongoDB数据库:

Database = <<"test">>.
{
   ok, Connection} = mc_worker_api:connect ([{
   database, Database}]).

建立连接时可以传递一些参数,具体的参数见文档,为了方面后面对源码的理解,我们来分析其中几个参数:

  • login和password:不解释。
  • w_mode:如果设置为safe|{safe,GetLastErrorParams},进程会在每次写入后发送getLastError请求,如果MongoDB报告写入错误,则剩余的写入会被中断并返回{failure, {write_failure, Reason}}错误;如果设置为unsafe,则假定每次写入必定成功,写入失败会被忽略。
  • next_req_fun:会在进程每次向MongoDB发送请求后执行,可以用来优化进程池性能(It can be use to optimise pool usage)。如果使用的是poolboy,可以用{next_req_fun, fun() -> poolboy:checkin(?DBPOOL, self()) end}使得工作进程(worker)在发送请求后马上被进程池回收(poolboy的进程池启动策略需要是{strategy,fifo})。

关于GetLastErrorParams,在MongoDB关于getLastError的文档写到:

Changed in version 2.6: A new protocol for write operations integrates write concerns with the write operations, eliminating the need for a separate getLastError.

就是说getLastError已经在2.6之后的Database Command已经用不上了,但在MongoDB Wire Protocol里还保留着,这点值得留意。

写入

这几种都属于写方法。可以使用mc_worker_api:insertmc_worker_api:updatemc_worker_api:delete完成数据库写入操作。

插入maps:

Collection = <<"test">>.
mc_worker_api:insert(Connection, Collection, #{
   <<"name">> => <<"Yankees">>, <<"home">> =>
  #{
   <<"city">> => <<"New York">>, <<"state">> => <<"NY">>}, <<"league">> => <<"American">>}),

删除文档,需要指定Selector:

mc_worker_api:delete(Connection, Collection, Selector).

读取

使用mc_worker_api:findmc_worker_api:find_one读取数据:

{
   ok, Cursor} = mc_worker_api:find(Connection, Collection, Selector)

find_onefind的不同在于,前者直接返回查询结果(文档),后者返回一个游标(cursor)进程的pid,可以在mc_cursor.erl模块中查看游标的用法:

Result = mc_cursor:next(Cursor),
mc_cursor:close(Cursor),

除了selector,还可传入projector过滤查询结果:

mc_worker_api:find_one(Connection, Collection, {
   }, #{
   projector => #{
   <<"value">> => true}).

更新

使用mc_worker_api:update$set进行更新,不多解释:

Command = #{
   <<"$set">> => #{
   
    <<"quantity">> => 500,
    <<"details">> => #{
   <<"model">> => "14Q3", <<"make">> => "xyz"},
    <<"tags">> => ["coats", "outerwear", "clothing"]
}},
mc_worker_api:update(Connection, Collection, #{
   <<"_id">> => 100}, Command),

创建索引

使用mc_worker_api:ensure_index/3创建索引。

mc_worker_api:ensure_index(Connection, Collection, #{
   <<"key">> => #{
   <<"index">> => 1}}).  %simple
mc_worker_api:ensure_index(Connection, Collection, #{
   <<"key">> => #{
   <<"index">> => 1}, <<"name">> => <<"MyI">>}).  %advanced
mc_worker_api:ensure_index(Connection, Collection, #{
   <<"key">> => #{
   <<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值