Giter VIP home page Giter VIP logo

mongodb-erlang's Introduction

This is the MongoDB driver for Erlang.

Run tests Enot

Usage

Add this repo as the dependency: Rebar

{deps, [
  {mongodb, ".*",
   {git, "git://github.com/comtihon/mongodb-erlang", {tag, "<Latest tag>"}}}
   ]
}

Erlang.mk

DEPS = mongodb
dep_mongodb = git https://github.com/comtihon/mongodb-erlang.git <Latest tag>

Where Latest tag is the latest tag from github.

Installing

If you want to use it from command line - download and compile the application:

$ git clone git://github.com/comtihon/mongodb-erlang.git mongodb
$ cd mongodb
$ make

You will need erlang 18+ and make installed.

Starting and using the api

Start all applications, needed by mongodb

> application:ensure_all_started (mongodb).

Important: mongoc API was changed in 3.0.0. mc_cursor API was changed in 3.0.0.

This driver has two api modules - mc_worker_api and mongo_api. mc_worker_api works directly with one connection, while all mongo_api interfaces refer to mongoc pool. Although mongoc is not stable for now you should use it if you have shard and need to determine mongo topology. If you are choosing between using mongos and using mongo shard with mongo_api - prefer mongos and use mc_worker_api.

mc_worker_api -- direct connection client

Connecting

To connect to a database test on mongodb server listening on localhost:27017 (or any address & port of your choosing) use mc_worker_api:connect/1.

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

mc_worker_api:connect returns {error, Reason} if it failed to connect. See arguments you can pass in mc_worker_api.erl type spec:

-type arg() :: {database, database()}
| {login, binary()}
| {password, binary()}
| {w_mode, write_mode()}
| {r_mode, read_mode()}
| {host, list()}
| {port, integer()}
| {register, atom() | fun()}
| {next_req_fun, fun()}.

To connect mc_worker in your supervised pool, use mc_worker:start_link/1 instead and pass all args to it.

safe, along with {safe, GetLastErrorParams} and unsafe, are write-modes. Safe mode makes a getLastError request after every write in the sequence. If the reply says it failed then the rest of the sequence is aborted and returns {failure, {write_failure, Reason}}, or {failure, not_master} when connected to a slave. An example write failure is attempting to insert a duplicate key that is indexed to be unique. Alternatively, unsafe mode issues every write without a confirmation, so if a write fails you won't know about it and remaining operations will be executed. This is unsafe but faster because you there is no round-trip delay.

master, along with slave_ok, are read-modes. master means every query in the sequence must read fresh data (from a master/primary server). If the connected server is not a master then the first read will fail, the remaining operations will be aborted, and mongo:do will return {failure, not_master}. slave_ok means every query is allowed to read stale data from a slave/secondary (fresh data from a master is fine too).

Read-modes only apply to the deprecated mc_worker_api query commands. Pass a readopts map, like #{<<"mode">> => <<"primary">>} to an mc_worker_api function like find_one(Conn, Coll, Selector, [{readopts, #{<<"mode">> => <<"primary">>}}]) for the new API.

If you set {register, Name} option - mc_worker process will be registered on this Name, or you can pass function fun(pid()), which it runs with self pid. If you set {login, Login} and {password, Password} options - mc_worker will try to authenticate to the database.

next_req_fun is a function caller every time, when worker sends request to database. It can be use to optimise pool usage. When you use poolboy transaction (or mongoc transaction, which use poolboy transaction) - mc_worker sends request to database and do nothing, waiting for reply. You can use {next_req_fun, fun() -> poolboy:checkin(?DBPOOL, self()) end} to make workers return to pool as soon as they finish request. When response from database comes back - it will be saved in mc_worker msgbox. Msgbox will be processed just before the next call to mc_worker. Notice, that poolboy's pool should be created with {strategy, fifo} to make uniform usage of pool workers.

Writing

After you connected to your database - you can carry out write operations, such as insert, update and delete:

> Collection = <<"test">>.
> mc_worker_api:insert(Connection, Collection, [
                                                   #{<<"name">> => <<"Yankees">>,
                                                     <<"home">> => #{<<"city">> => <<"New York">>, <<"state">> => <<"NY">>},
                                                     <<"league">> => <<"American">>},
                                                   #{<<"name">> => <<"Mets">>,
                                                     <<"home">> => #{<<"city">> => <<"New York">>, <<"state">> => <<"NY">>},
                                                     <<"league">> => <<"National">>},
                                                   #{<<"name">> => <<"Phillies">>,
                                                     <<"home">> => #{<<"city">> => <<"Philadelphia">>, <<"state">> => <<"PA">>},
                                                     <<"league">> => <<"National">>},
                                                   #{<<"name">> => <<"Red Sox">>,
                                                     <<"home">>=> #{<<"city">> => <<"Boston">>, <<"state">> => <<"MA">>},
                                                     <<"league">> => <<"American">>}
                                                 ]),

An insert example (from mongo_SUITE test module). Connection is your Connection, got from mc_worker_api:connect, Collection is your collection name, Doc is something, you want to save. Doc will be returned, if insert succeeded. If Doc doesn't contains _id field - an updated Doc will be returned - with automatically generated '_id' fields. If error occurred - Connection will fall.

> mc_worker_api:delete(Connection, Collection, Selector).

Delete example. Connection is your Connection, Collection - is a collection you want to clean. Selector is the rules for cleaning. If you want to clean everything - pass empty {}. You can also use maps instead bson documents:

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

Reading

To call read operations use find, find_one:

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

All params similar to delete. The difference between find and find_one is in return. Find_one just returns your result, while find returns you a Cursor - special process' pid. You can query data through the process with the help of `mc_cursor' module.

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

Important! Do not forget to close cursors after using them! mc_cursor:rest closes the cursor automatically.

To search for params - specify Selector:

mc_worker_api:find_one(Connection, Collection, #{<<"key">> => <<"123">>}).

will return one document from collection Collection with key == <<"123">>.

mc_worker_api:find_one(Connection, Collection, #{<<"key">> => <<"123">>, <<"value">> => <<"built_in">>}).

will return one document from collection Collection with key == <<"123">> and value == <<"built_in">>. Tuples {<<"key">>, <<"123">>} in first example and {<<"key">>, <<"123">>, <<"value">>, <<"built_in">>} are selectors.

For filtering result - use Projector:

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

will return one document from collection Collection with fetching only _id and value.

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

will return your data without key and value params. If there is no other data - only _id will be returned.

Updating

To add or update field in document - use mc_worker_api:update function with $set param. This updates selected fields:

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

This will add new field expired, if there is no such field, and set it to true.

Command = #{<<"$set">> => #{<<"expired">> => true}},
mc_worker_api:update(Connection, Collection, #{<<"_id">> => 100}, Command),

This will update fields in nested documents.

Command = #{<<"$set">> => #{<<"details.make">> => "zzz"}},
mc_worker_api:update(Connection, Collection, #{<<"_id">> => 100}, Command),

This will update elements in array.

Command = #{<<"$set">> => #{
    <<"tags.1">> => "rain gear",
    <<"ratings.0.rating">> => 2
  }},
mc_worker_api:update(Connection, Collection, #{'_id' => 100}, Command),

For result of executing this functions - see mongo_SUITE update test.

Creating indexes

To create indexes - use mc_worker_api:ensure_index/3 command:

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">> => #{<<"index">> => 1}, <<"name">> => <<"MyI">>, <<"unique">> => true, <<"dropDups">> => true}).  %full

ensure_index takes mc_worker' pid or atom name as first parameter, collection, where to create index, as second parameter and bson document with index specification - as third parameter. In index specification one can set all or only some parameters. If index specification is not full - it is automatically filled with values: name, Name, unique, false, dropDups, false, where Name is index's key.

Administering

This driver does not provide helper functions for commands. Use mc_worker_api:command directly and refer to the MongoDB documentation for how to issue raw commands.

Authentication

To authenticate use function mc_worker_api:connect, or mc_worker:start_link([...{login, <<"login">>}, {password, <<"password">>}...]

Timeout

By default timeout for all connections to connection gen_server is infinity. If you found problems with it - you can modify timeout. To modify it just add mc_worker_call_timeout with new value to your applications's env config.

Timeout for operations with cursors may be explicitly passed to mc_cursor:next/2, mc_cursor:take/3, mc_cursor:rest/2, and mc_cursor:foldl/5 functions, by default used value of cursor_timeout from application config, or infinity if cursor_timeout not specified.

Pooling

If you need simple pool - use modified Poolboy, which is included in this app's deps. As a worker module use mc_worker_api. If you need pool to mongo shard with determining topology - use mongo_api for automatic topology discovery and monitoring. It uses poolboy inside.

mongoc -- client with automatic MongoDB topology discovery and monitoring

You can use mongo_api.erl for easy working with mongoc.

Connection

For opening a connection to a MongoDB server you can call mongoc:connect/3:

{ok, Topology} = mongoc:connect(Seed, Options, WorkerOptions)

Where Seed contains information about host names and ports to connect and info about topology of MongoDB deployment.

So you can pass just a hostname with port (or tuple with single key) for connection to a single server deployment:

SingleSeed = "hostname:27017",
SingleSeedTuple = { single, "hostname:27017" }

If you want to connect to a replica set ReplicaSetName use this format of the Seed value:

ReplicaSeed = { rs, <<"ReplicaSetName">>, [ "hostname1:port1", "hostname2:port2"] }

To connect to a sharded cluster of mongos:

ShardedSeed = { sharded,  ["hostname1:port1", "hostname2:port2"] }

And if you want your MongoDB deployment metadata to be auto-discovered use the unknown type in the Seed tuple:

AutoDiscoveredSeed = { unknown,  ["hostname1:port1", "hostname2:port2"] }

mongoc topology Options

[
    { name,  Name },    % Name should be used for mongoc pool to be registered with
    { register,  Name },    % Name should be used for mongoc topology process to be registered with

    { pool_size, 5 }, % pool size on start
    { max_overflow, 10 },	% number of overflow workers be created, when all workers from pool are busy
    { overflow_ttl, 1000 }, % number of milliseconds for overflow workers to stay in pool before terminating
    { overflow_check_period, 1000 }, % overflow_ttl check period for workers (in milliseconds)

    { localThresholdMS, 1000 }, % secondaries only which RTTs fit in window from lower RTT to lower RTT + localThresholdMS could be selected for handling user's requests

    { connectTimeoutMS, 20000 },
    { socketTimeoutMS, 100 },

    { serverSelectionTimeoutMS, 30000 }, % max time appropriate server should be select by
    { waitQueueTimeoutMS, 1000 }, % max time for waiting worker to be available in the pool

    { heartbeatFrequencyMS, 10000 },    %  delay between Topology rescans
    { minHeartbeatFrequencyMS, 1000 },

    { rp_mode, primary }, % default ReadPreference mode - primary, secondary, primaryPreferred, secondaryPreferred, nearest

    { rp_tags, [{tag,1}] }, % tags that servers shoul be tagged by for becoming candidates for server selection  (may be an empty list)
]

mongoc WorkerOptions (as described in mongo Connecting chapter)

-type arg() :: {database, database()}
| {login, binary()}
| {password, binary()}
| {w_mode, write_mode()}.

More Documentation

API Docs - Documentation generated from source code comments

mongodb-erlang's People

Contributors

ahmah2009 avatar alttagil avatar andraus avatar antonsizov avatar christkv avatar comtihon avatar deadtrickster avatar dmsnell avatar getong avatar hachreak avatar hammingweight avatar kianmeng avatar kpoxman avatar kudryashov-sv avatar larrouse2015 avatar larshesel avatar monkey101 avatar mweibel avatar pmyarchon avatar readmecritic avatar russelldb avatar seansawyer avatar serzh avatar smcqueen avatar soplakanets avatar starstuck avatar superbobry avatar szemek avatar thesquad avatar varnerac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongodb-erlang's Issues

MongoDB 3.0 auth mechanism

Hi, is there any plan to support SCRAM-SHA-1 auth mechanism to work with MongoDB 3.0 ?

Best regards,

Morgan.

dynamically created atoms in soundrop/bson-erlang

Hi,
I'm trying to write an Erlang application that connects to MongoDB and I looked into using this client driver.

I notice that soundrop/bson-erlang (the rebar dependency) maps document field names to Erlang atoms using binary_to_atom. This is visible in the bson parser code (bson_binary:get_fields) and also mentioned in the blog post, http://blog.mongodb.org/post/7270427645/design-of-the-erlang-driver-for-mongodb .

I think it's very dangerous to use binary_to_atom like that, since atoms are not garbage collected and so document collections containing too many different field names can overrun memory in the Erlang node. I'd consider this a critical bug (in my application I can't control what's in documents and might even get malicious ones) so I can't use the driver like that. I'd urge a refactoring to not use atoms in this unsafe way, that the Erlang documentation advises against.

I thought about just modifying the driver and sending you a patch, but since it would be an API change, I decided I better ask your advice about it first. It's of course also possible that I'm missing something, in which case enlightenment is always appreciated. Please let me know your thoughts.

(Note: I tried emailing this but it bounced).

Thanks

--Paul

Can I set mongod socket always active once?

case dict:size(UReqStor) of
    0 -> ok;
    _ -> inet:setopts(State#state.socket, [{active, once}]) %TODO why not always active true?
  end,

When I use poolboy, mc_worker can't recognize tcp closed bucause socket not set active once when mc_worker is idle

Connection with login password

Hello, I'm trying to connect to remote mongo server 2.6.4 like this

mongo:connect([{database, list_to_binary(DB)}, {host, Host}, {port, Port}, {login, list_to_binary(U)}, {password, list_to_binary(P)}])

and getting this error

[error] CRASH REPORT Process <0.376.0> with 1 neighbours crashed with reason: bad argument in call to erlang:iolist_to_binary([{ok.......<<"my_login_here">>......in crypto:hash/2 line 223

Connection like this

mongo:connect([{database, list_to_binary(DB)}, {host, Host}, {port, Port}

works just fine in the same time.
Any ideas?

How to "save" Connection pid between queries?

I am writing backend storage for Erl db abstraction lib kvs.
There is start fun in kvs, that establish connection with mongoDB. How I can store connection, to re-use for future queries?

I understand that result of connection is PID of connection process, but what is next?

How mongodb-erlang suggest that external apps will use it? any recommendation?

distinct command does not work

I'm trying to get all the distinct values of some collection, I can get the result by executing db.$cmd.findOne({distinct: collection_name, key: some_key}) from within the shell. However, when I do:

mongo:do(safe, master, DbConn, some_db,
  fun() ->
    mongo:command(
      {
        distinct, some_collection,
        key, some_key
      }
    )
  end
)

I always get a blank list. I'm working on Ubuntu 12.04 + MongoDb 2.2.1 + Erlang R15B02.

Cannot connect to remote Mongo server

This driver seems very nice. I use it in my elixir project.
This is my code to connect to my remote mongo server. But it returns error.

iex> :mongo.connect("db_name", "account", "password", "safe", "master", [{"host", "example.com"}, {"port", 27017}])
** (EXIT from #PID<0.88.0>) {:errmsg, "auth failed", :code, 18}

(I've tried to connect by my local mongo client and it works.)
Is this right format of the :mongo.connect/6 command when use in elixir?
Please help me!

Can't connect to DB after integer exceeds 32 bits

Our server is using mongoerl in master branch. We found a bug which causes our server down about every month in mongoerl. The trace is as follows:

["web request failed",
{path,"l"},
{type,error},
{what,{badmatch,{-2146148680,
{reply,false,false,true,0,0,
[{setName,<<"rs0">>,ismaster,true,secondary,false,
hosts,
[<<"ip-10-121-13-170:27017">>,
<<"ip-10-121-12-150:27017">>,
<<"ip-10-121-12-108:27017">>],
primary,<<"ip-10-121-13-170:27017">>,me,
<<"ip-10-121-13-170:27017">>,
maxBsonObjectSize,16777216,
maxMessageSizeBytes,48000000,localTime,
{1371,74346,818000},
ok,1.0}]},
<<>>}}},

After looking into the source of mongodb-erlang, I think this is mainly because that after request_id was requested more than 2147483647 times(every time it will use ets:update_counter to increase by 1), it will be larger than 32 bit int, then this error will occur. We are using this in production environment so we need a urgent fix. I checked refactor branch, it seems not many documents on that new branch with new interfaces and so it's impossible for us to risk upgrading it to new. Could anyone please tell me what to do to avoid this problem, probably a quick fix for this in mongoerl?

Thanks very much

how to use find api to regex data

I want use selector {field_name, '$regex', "/data/i"}
find data

mongod-2.6version is ok

mongod-3.0version is badValue '$regex' to a string

connect/6 example

Hi, could you please provide example how to use connect/6 with empty username and password
Why I need this?
I have not auth, but want to tune DB server IP and port.

Thanks in advance.

Authentication problem

While trying to connect to mongodb with login and password, i am getting <<"Can't pass authentification">>.
Login & Password are correct and working with other application.

mc_worker:start_link([{database, <<"database">>},{login, <<"admin">>},{password, <<"password">>},{host,"x.x.x.x"},{port,27017}]).

[error] CRASH REPORT Process <0.478.0> with 1 neighbours crashed with reason: <<"Can't pass authentification">> in mc_auth_logic:scram_sha_1_auth/4 line 34

Can't pass authentification

Версия монги 3.0.
Версия erlang 18.
Cypto запущено.
Подключение:

ok, Connection} = mongo:connect ([
    {database, <<"dbname">>},
    {login, <<"user">>},
    {password, <<"pass">>}
  ])

в итоге "Can't pass authentification".
В эксепшене:
"A: error, B: {badmatch,{false,#{<<99,111,100,101>>=>18,<<101,114,114,109,115,103>>=><<65,117,116,104,101,110,116,105,99,97,116,105,111,110,32,102,97,105,108,101,100,46>>}}}".
Либо с другой учёткой:
"A: error, B: undef"

=CRASH REPORT==== 18-Aug-2015::12:47:27 ===
crasher:
initial call: mc_worker:init/1
pid: <0.96.0>
registered_name: []
exception error: <<"Can't pass authentification">>
in function mc_auth_logic:scram_sha_1_auth/4 (src/core/mc_auth_logic.erl, line 42)
in call from mc_worker:init/1 (src/connection/mc_worker.erl, line 41)
ancestors: [<0.94.0>]
messages: []
links: [<0.94.0>,#Port<0.1592>]
dictionary: [{random_seed,{879,21160,14733}}]
trap_exit: false
status: running
heap_size: 987
stack_size: 27
reductions: 2920
neighbours:
neighbour: [{pid,<0.94.0>},
{registered_name,[]},
{initial_call,{erlang,apply,2}},
{current_function,{proc_lib,sync_wait,2}},
{ancestors,[]},
{messages,[]},
{links,[<0.26.0>,<0.96.0>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,233},
{stack_size,29},
{reductions,498}]
** exception exit: <<"Can't pass authentification">>

С теми же данными из php подключаюсь без проблем. Куда копать?

Change rebar.config

In file rebar.config change atom fail_on_warning to warnings_as_errors.
Atom fail_on_warning is deprecated

BinData(4, binary) - how to achieve?

Hi,

currently I'm using the following erlang tuple to generate an "_id" with BinData(3, binary):

generate_objectid_subtype3() ->
    {bin, uuid, uuid:uuid4()}.

How can I achieve that MongoDB will get a BinData of Type 4?

Add LICENSE

Could you please add licensing terms? I know this driver has long history starting from 10gen but anyway.

Undefined function error

It throws undefined function error

$ erl -pa ebin deps/*/ebin
Erlang R16B (erts-5.10.1) [source-05f1189] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)
1> application:start(bson).
ok
2> application:start(mongodb).
ok
3> mongo:connect({localhost, 27017}).
** exception error: undefined function mongo:connect/1

Why?

Finish refactoring

  • made safe write confirmation and write in one transaction. ( comtihon:refactor )

How to sort and limit a find query ?

I have been searching everywhere, I can't find for the life of me how to sort a find query and ordering it... has it been forget ?

Other less supported drivers does it, I do see why this one couldn't be able to...

Any clue would be greatly appreciated.

distinct query

Hi,

I can't figure out which api method to use to write a "distinct" query with both keys and selectors.

Any help please ?

How to retrieve the actual value of an id?

I have tried the bson:utf8() method... but doesn't help.

Basically how do I turn the binary representation into a string-like representation?

<<83,22,19,109,142,79,136,52,52,0,0,1>> --> "5314e0d68e4f8823fb000001"

Give a way to query by id

mongo:find_one(my_collection, {<<"_id">>, <<82,29,123,102,44,196,167,32,184,0,0,1>>}). %% Does not work, nor does replacing with <<"ObjectId("my_id")">> or the base64 representation.

How do I query for the id?

Support for mongo's `Infinity`

Loading documents that contains Infinity fails due to BSON parsers can't decode the float:

// insert in mongo shell
db.test.insert({"hello": Infinity})
# try to query back
:poolboy.transaction :mongodb, fn(conn) -> :mongo.find_one(conn, :test, %{}) end
** (exit) exited in: :gen_server.call(#PID<0.3001.0>, {:query, false, false, false, false, :test, 0, -1, %{}, []}, :infinity)
    ** (EXIT) an exception was raised:
        ** (MatchError) no match of right hand side value: <<0, 0, 0, 0, 0, 0, 240, 127>>
            (bson) src/bson_binary.erl:87: :bson_binary.get_field/4
            (bson) src/bson_binary.erl:144: :bson_binary.get_field/2
            (bson) src/bson_binary.erl:54: :bson_binary.get_fields/2
            (bson) src/bson_binary.erl:40: :bson_binary.get_map/1
            (mongodb) src/core/mongo_protocol.erl:111: :mongo_protocol.get_docs/3
            (mongodb) src/core/mongo_protocol.erl:92: :mongo_protocol.get_reply/1
            (mongodb) src/connection/mc_worker_logic.erl:68: :mc_worker_logic.decode_responses/2
            (mongodb) src/connection/mc_worker.erl:102: :mc_worker.handle_info/2

There is a pull request for it in the bson-erlang repo put i'm posting it here for reference.

Connect to mongo with auth

Can someone give me an example of connect to a remote mongodb server with username and password? I tried several ways but didn't work.

Best Regards,

ensure_index syntax

Does anyone know about ensure_syntax?

I tried

mongo:ensure_index(DBConn, conversations, {key, {page_id, 1}, unique, true, dropDups, true})

but not work at all

Support for MONGOHQ?

Hi

I have been using this plugin to connect to mongohq

While I can establish an initial connection to the databse it throws an error everytime i try to do a query such as find:

=ERROR REPORT==== 15-Jul-2013::12:34:45 ===
      Conn: GET /
    Reason: (MatchError) no match of right hand side value: {:failure, :unauthorized}
Stacktrace:
  lib/dynamodemoapp/models/task.ex:2: Tasks.find_all/2

The custom code above is just a wrapper to :mongo.find

It seems that there is an authorization error failure? and i can't work out why it is causing it as it uses the same connection parameters as if you are connecting to localhost?

any help or pointers will be useful

thanks!

Newby: undefined function mongo:connect/1

I followed the README and got stuck at trying to connect to my local instance with no auth.

$  erl -pa mongodb/ebin mongodb/deps/bson/ebin
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1>  application:start (bson).                  
ok
2>  application:start (mongodb).
ok
3> Database = <<"test">>.
<<"test">>
4> {ok, Connection} = mongo:connect (Database).
** exception error: undefined function mongo:connect/1

the compile went fine, without errors.

Any suggestions?

p.s. i read the issue from 2 years ago that the api may have changed, but I saw the README being updated today, so I assume it correct now...

compiling error

When compiling the driver using the cmd 'erlc -o ebin -I include -I .. src/*.erl
', I get the error info:
src/mongo.erl:333: syntax error before: '.'
src/mongo.erl:32: function add_user/3 undefined
src/mongo.erl:330: spec for undefined function mongo:add_user/3

And then I fixed it with:

before
add_user (Permission, Username, Password) ->
User = case find_one (system.users, {user, Username}) of {} -> {user, Username}; {Doc} -> Doc end,
Rec = {readOnly, case Permission of read_only -> true; read_write -> false end, pwd, pw_hash (Username, Password)},
save (system.users, bson:merge (Rec, User)).

after
add_user (Permission, Username, Password) ->
User = case find_one ('system.users', {user, Username}) of {} -> {user, Username}; {Doc} -> Doc end,
Rec = {readOnly, case Permission of read_only -> true; read_write -> false end, pwd, pw_hash (Username, Password)},
save ('system.users', bson:merge (Rec, User)).

How to insert an ISODate to MongoDB

Hi,

currently I insert datetimes as ISO8601 timestamp string but I'd like to change that to the MongoDB Datatype ISODate.

How can I achieve this?

Thanks

maps support?

Does mongodb-erlang support the maps syntax ?

maps is easy for insert and match the query result

Example:

mongo:insert(Connection, Collection, #{name => <<"Tom">>, age => 22 }),
mongo:update(Connection, Collection, #{'$set' => #{age => 33 }}),
Data = mongo:find_one(Connection, Collection, #{age => 30}),
#{name := Name} = Data

mongodb-erlang's modify function return error

Hi, Mr Christkv, When I use mongodb-erlang's modify function,I had a problem.Could give me some tips, thank you very much!

erlang code ---

test_modify() ->
Actions = fun() -> mongo:modify(c1, {x,{'$lt',100}}, {y,10}) end,
do(Actions).

do(Actions) ->
case test_connection() of
{ok, Conn} ->
{State, Reason} = mongo:do(safe, master, Conn, testdb, Actions),
case {State, Reason} of
{failure, Reason} ->
mongo:disconnect(Conn),
{failure, Reason};
{ok, Result} ->
mongo:disconnect(Conn),
{ok, Result}
end;
{error, Reason} ->
{error, Reason}
end.
end code -----

my collections is :

mongo shell ----

db.c1.find();
{ "_id" : ObjectId("503b252196d6a81fb4000005"), "x" : 5, "y" : 6 }
{ "_id" : ObjectId("503b26ef96d6a81fb4000006"), "x" : 10, "y" : 11 }
{ "_id" : ObjectId("503b26ef96d6a81fb4000007"), "x" : 12, "y" : 13 }
{ "_id" : ObjectId("503b26ef96d6a81fb4000008"), "x" : 14, "y" : 15 }
end mongo shell ---

When running : test_modify/0 , there catch a error:

error code ---
{failure,{write_failure,10158,
<<"multi update only works with $ operators">>}}
end error code ---

Instructions in Readme are outdated.

Subj.
First of all: installing into lib directory returned by code:lib_dir() does not work as per instructions. In reality you have to create two directories:
one for mongodb, one for bson, e.g.
/usr/lib64/erlang/lib/mongo-master
and
/usr/lib64/erlang/lib/bson-master
Then it'll work.
Second - I'm now reading through code, as module mongo doesn't have connect function. I guess I have to use mongo_connect module, but there is no mention of it in docs, so one has to dig into the code. Bless open-source, by the way :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.