Current section

Files

Jump to
gleam_mongo src mongo@aggregation.erl
Raw

src/mongo@aggregation.erl

-module(mongo@aggregation).
-compile(no_auto_import).
-export([aggregate/1, match/2, lookup/5, project/2, add_fields/2, sort/2, group/2, skip/2, limit/2, exec/1]).
-export_type([pipeline/0]).
-opaque pipeline() :: {pipeline,
mongo@client:collection(),
list(bson@types:value())}.
-spec aggregate(mongo@client:collection()) -> pipeline().
aggregate(Collection) ->
{pipeline, Collection, []}.
-spec match(pipeline(), bson@types:value()) -> pipeline().
match(Pipeline, Doc) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$match"/utf8>>, Doc}]}]
)}.
-spec lookup(pipeline(), binary(), binary(), binary(), binary()) -> pipeline().
lookup(Pipeline, From, Local_field, Foreign_field, Alias) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document,
[{<<"$lookup"/utf8>>,
{document,
[{<<"from"/utf8>>, {str, From}},
{<<"localField"/utf8>>, {str, Local_field}},
{<<"foreignField"/utf8>>, {str, Foreign_field}},
{<<"as"/utf8>>, {str, Alias}}]}}]}]
)}.
-spec project(pipeline(), bson@types:value()) -> pipeline().
project(Pipeline, Doc) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$project"/utf8>>, Doc}]}]
)}.
-spec add_fields(pipeline(), bson@types:value()) -> pipeline().
add_fields(Pipeline, Doc) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$addFields"/utf8>>, Doc}]}]
)}.
-spec sort(pipeline(), bson@types:value()) -> pipeline().
sort(Pipeline, Doc) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$sort"/utf8>>, Doc}]}]
)}.
-spec group(pipeline(), bson@types:value()) -> pipeline().
group(Pipeline, Doc) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$group"/utf8>>, Doc}]}]
)}.
-spec skip(pipeline(), integer()) -> pipeline().
skip(Pipeline, Count) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$skip"/utf8>>, {integer, Count}}]}]
)}.
-spec limit(pipeline(), integer()) -> pipeline().
limit(Pipeline, Count) ->
{pipeline,
erlang:element(2, Pipeline),
gleam@list:append(
erlang:element(3, Pipeline),
[{document, [{<<"$limit"/utf8>>, {integer, Count}}]}]
)}.
-spec exec(pipeline()) -> {ok, list(bson@types:value())} |
{error, mongo@utils:mongo_error()}.
exec(Pipeline) ->
case mongo@client:execute(
erlang:element(2, Pipeline),
{document,
[{<<"aggregate"/utf8>>,
{str, erlang:element(3, erlang:element(2, Pipeline))}},
{<<"cursor"/utf8>>, {document, []}},
{<<"pipeline"/utf8>>, {array, erlang:element(3, Pipeline)}}]}
) of
{ok, Result} ->
[{<<"cursor"/utf8>>, {document, Result@1}}, {<<"ok"/utf8>>, Ok}] = Result,
[{<<"firstBatch"/utf8>>, {array, Docs}},
{<<"id"/utf8>>, _@1},
{<<"ns"/utf8>>, _@2}] = Result@1,
case Ok of
{double, 1.0} ->
{ok, Docs};
_@3 ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code, Msg}} ->
{error, {mongo_error, Code, Msg, null}}
end.