-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, nil}. exec(Pipeline) -> case mongo@client:execute( erlang:element(2, Pipeline), {document, [{<<"cursor"/utf8>>, {document, []}}, {<<"pipeline"/utf8>>, {array, erlang:element(3, Pipeline)}}, {<<"aggregate"/utf8>>, {str, erlang:element(3, erlang:element(2, Pipeline))}}]} ) of {ok, Result} -> [{<<"ok"/utf8>>, Ok}, {<<"cursor"/utf8>>, {document, Result@1}}] = Result, [{<<"ns"/utf8>>, _@1}, {<<"id"/utf8>>, _@2}, {<<"firstBatch"/utf8>>, {array, Docs}}] = Result@1, case Ok of {double, 1.0} -> {ok, Docs}; _@3 -> {error, nil} end; {error, nil} -> {error, nil} end.