Getting Started
View SourceThis guide walks you through installing and using Barrel DocDB from Erlang. barrel_docdb is an embedded document store: you call it in-process through the barrel_docdb module. You'll have a working database in under 5 minutes.
HTTP access
barrel_docdb has no built-in HTTP server. To reach a database over the wire (REST/JSON), run the
barrel_serverapp, which exposes barrel_docdb over HTTP. See the umbrella REST server guide (docs/guides/rest-server.md).
Prerequisites
- Erlang/OTP 28+
Installation
Erlang (Embedded)
Add to your rebar.config:
{deps, [
{barrel_docdb, "~> 1.0"}
]}.Then fetch dependencies:
rebar3 get-deps
rebar3 compile
Build from Source
Clone and build:
git clone https://github.com/barrel-db/barrel.git
cd barrel
rebar3 compile
rebar3 shell
Your First Database
Start the Application
application:ensure_all_started(barrel_docdb).Create a Database
{ok, _Db} = barrel_docdb:create_db(<<"myapp">>).Store a Document
With an auto-generated ID:
{ok, #{<<"id">> := DocId, <<"rev">> := Rev}} =
barrel_docdb:put_doc(<<"myapp">>, #{
<<"type">> => <<"user">>,
<<"name">> => <<"Alice">>,
<<"email">> => <<"alice@example.com">>
}).With a specific ID:
{ok, #{<<"rev">> := Rev}} =
barrel_docdb:put_doc(<<"myapp">>, #{
<<"id">> => <<"user-alice">>,
<<"type">> => <<"user">>,
<<"name">> => <<"Alice">>
}).Retrieve a Document
{ok, Doc} = barrel_docdb:get_doc(<<"myapp">>, <<"user-alice">>).
%% Doc = #{<<"id">> => <<"user-alice">>, <<"_rev">> => <<"1-...">>, ...}Update a Document
Include the current <<"_rev">> value from the document you fetched:
{ok, #{<<"rev">> := NewRev}} =
barrel_docdb:put_doc(<<"myapp">>, Doc#{
<<"name">> => <<"Alice Smith">>,
<<"role">> => <<"admin">>
}).Delete a Document
Pass the current revision in the options:
{ok, _} = barrel_docdb:delete_doc(<<"myapp">>, <<"user-alice">>, #{rev => NewRev}).Querying Documents
Barrel DocDB provides declarative queries with automatic path indexing. No need to create indexes manually.
Find all users:
{ok, Users, _Meta} = barrel_docdb:find(<<"myapp">>, #{
where => [{path, [<<"type">>], <<"user">>}]
}).Find admins:
{ok, Admins, _Meta} = barrel_docdb:find(<<"myapp">>, #{
where => [
{path, [<<"type">>], <<"user">>},
{path, [<<"role">>], <<"admin">>}
]
}).With pagination. Meta carries has_more and, when there is more, a continuation token to pass back:
{ok, Page, Meta} = barrel_docdb:find(<<"myapp">>, #{
where => [{path, [<<"type">>], <<"user">>}],
limit => 10
}),
case Meta of
#{has_more := true, continuation := Token} ->
{ok, More, _} = barrel_docdb:find(<<"myapp">>,
#{where => [{path, [<<"type">>], <<"user">>}], limit => 10},
#{continuation => Token});
#{has_more := false} ->
ok
end.You can also run BQL text with barrel_docdb:query/2,3:
{ok, Rows, _Meta} = barrel_docdb:query(<<"myapp">>,
<<"SELECT name FROM db WHERE type = 'user' LIMIT 10">>).Watching for Changes
Subscribe to real-time changes using MQTT-style path patterns. Notifications are delivered to the calling process as messages.
Subscribe to all changes:
{ok, _SubRef} = barrel_docdb:subscribe(<<"myapp">>, <<"#">>),
receive
{barrel_change, <<"myapp">>, Change} ->
io:format("Change: ~p~n", [Change])
end.Subscribe to user changes only:
{ok, SubRef} = barrel_docdb:subscribe(<<"myapp">>, <<"type/user/#">>).Unsubscribe:
barrel_docdb:unsubscribe(SubRef).To read changes since a point instead of subscribing, use barrel_docdb:get_changes/2,3. See Changes Feed.
Working with Attachments
Store binary files (images, documents, etc.) alongside your documents.
Store an attachment:
Data = <<"Hello, World!">>,
{ok, _} = barrel_docdb:put_attachment(<<"myapp">>, <<"user-alice">>,
<<"greeting.txt">>, Data).Retrieve an attachment:
{ok, Binary} = barrel_docdb:get_attachment(<<"myapp">>, <<"user-alice">>,
<<"greeting.txt">>).List attachments:
AttNames = barrel_docdb:list_attachments(<<"myapp">>, <<"user-alice">>).
%% Returns [<<"greeting.txt">>]For large files, stream with open_attachment_stream/3 and read_attachment_chunk/1.
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
BARREL_DATA_DIR | data/barrel_docdb | Data directory |
Erlang Configuration
In sys.config:
[
{barrel_docdb, [
{data_dir, "data/barrel_docdb"}
]}
].HTTP listener settings (port, TLS) live in barrel_server, not barrel_docdb. See the umbrella REST server guide (docs/guides/rest-server.md).
Next Steps
Now that you have Barrel DocDB running, explore these features:
- Queries - Advanced query syntax, operators, and filtering
- Changes Feed - Real-time subscriptions and MQTT-style patterns
- Replication - Sync data between nodes with filtering
- API reference - Complete function documentation
Troubleshooting
Document Update Fails with Conflict
If you get a conflict error when updating, ensure you're passing the current revision. barrel_docdb uses MVCC (Multi-Version Concurrency Control) to prevent lost updates: read the document first, then include its
<<"_rev">>in the update (or pass#{rev => Rev}todelete_doc/3).%% Get the current revision first {ok, Doc} = barrel_docdb:get_doc(<<"myapp">>, <<"doc1">>), %% Then write back the document you just read {ok, _} = barrel_docdb:put_doc(<<"myapp">>, Doc#{<<"name">> => <<"updated">>}).
Serving over HTTP
To expose a database over REST/JSON (including TLS), run the
barrel_serverapp rather than barrel_docdb on its own. See the umbrella REST server guide (docs/guides/rest-server.md).