I am working on Tash which is an Open Source C++ library for ArangoDB Database which includes APIs for HTTP based document access and a query builder for AQL (Arango Query Language). These are a few example usages.
1 2 3 4 5 6 7 8 std ::string name = "Hijibijbij" ;tash::shell shell ("school" ) ; shell << select("s" ).in("students" ) / filter((clause("s.name" ) == name) && (clause("s.fathers_name" ) == name)) / sort().asc("s._key" ) / yield("s" ); nlohmann::json result; shell >> result;
The above generates an equivalent AQL and execute it over the arangodb connection
1 2 3 4 FOR s IN students FILTER s.name == "Hijibijbij" AND s.fathers_name == "Hijibijbij" SORT s._key ASC RETURN s
Along with AQL generation it also performs normal HTTP API based document access.
1 2 3 4 5 6 7 8 9 10 11 tash::vertex students (school, "students" ) ;if (students.exists() == boost::beast::http::status::not_found){ students.create(); } nlohmann::json document = { {"name" , "Hijibijbij" }, {"fathers_name" , "Hijibijbij" }, {"uncles_name" , "Hijibijbij" } }; boost::beast::http::status status = students.add(document); nlohmann::json hijibijbij = students.by_key(document["_key" ].get<std ::string >());
Unlike Fuerte it does not require velocypack or node. Instead it uses nlohmann::json and Boost.Beast libraries
Building prerequisites
C++ compiler
CMake
boost library
nlohmann::json [OPTIONAL] (tash ships with a single file version of nlohmann::json)
compiling 1 2 3 4 5 git clone https://gitlab.com/neel.basu/tash.git mkdir build cd buildcmake .. make
Basic Example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> #include <tash/arango.h> #include <boost/format.hpp> #include <boost/beast/http/status.hpp> int main () { tash::shell school ("school" ) ; if (school.exists() == boost::beast::http::status::not_found){ school.create(); } tash::vertex students (school, "students" ) ; if (students.exists() == boost::beast::http::status::not_found){ students.create(); } nlohmann::json document = { {"name" , "Hijibijbij" }, {"fathers_name" , "Hijibijbij" }, {"uncles_name" , "Hijibijbij" } }; boost::beast::http::status status = students.add(document); if (status == boost::beast::http::status::accepted){ std ::cout << boost::format("document created with key %1%" ) % document["_key" ] << std ::endl ; }else { std ::cout << "Failed to create document with error " << status << std ::endl ; } nlohmann::json hijibijbij = students.by_key(document["_key" ].get<std ::string >()); std ::cout << "retrieved document " << std ::endl ; std ::cout << hijibijbij << std ::endl ; return 0 ; }
AQL (Arango Query Language) Builder Retrieve / Filter / Sort 1 2 3 4 5 6 7 tash::shell shell ("school" ) ; shell << select("s" ).in("students" ) / filter((clause("s.name" ) == name) && (clause("s.fathers_name" ) == name)) / sort().asc("s._key" ) / yield("s" ); nlohmann::json result; shell >> result;
1 2 3 4 FOR s IN students FILTER s.name == "Hijibijbij" AND s.fathers_name == "Hijibijbij" SORT s._key ASC RETURN s
1 2 3 4 select("s" ).in("students" ) / filter((clause("s.name" ) == "s.fathers_name" )) / sort().asc("s._key" ) / yield("s" );
1 2 3 4 FOR s IN students FILTER s.name == s.fathers_name SORT s._key ASC RETURN s
insert insert single row 1 2 3 4 insert(nlohmann::json{ {"name" , "tash" }, {"fathers_name" , "tash" } }).in("students" );
1 INSERT {"fathers_name":"tash","name":"tash"} INTO students
insert multiple rows 1 2 3 4 select("u" ).in({ {"name" , "tash" }, {"fathers_name" , "tash" } }) / insert("u" ).in("students" )
1 2 FOR u IN {"fathers_name":"tash","name":"tash"} INSERT u INTO students
generate rows
in nlohmann::json
string values are always quoted
tash::assign
generates non-nested key value pairs (non-nested json)
C style strings are unquoted, std::string
is quoted
1 2 3 4 5 6 select("i" ).in(1 , 10 ) / insert( assign("name" , "CONCAT('tash', i)" ) .assign("gender" , "(i % 2 == 0 ? 'f' : 'm')" ) .assign("fathers_name" , std ::string ("tash" )) ).in("users" )
1 2 3 4 5 6 FOR i IN 1..10 INSERT { name: CONCAT('test', i), gender: (i % 2 == 0 ? 'f' : 'm'), fathers_name: "tash" } INTO users
update 1 2 3 4 5 update(nlohmann::json{ {"_key" , 1234 } }).with({ {"uncles_name" , "tash" } }).in("students" )
1 UPDATE {"_key":1234} WITH {"uncles_name":"tash"} IN students
let 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (let("date" ) = "DATE_NOW()" ) / select("user" ).in("users" ) / filter(clause("user.isImportantUser" ) == "null" ) / (let("numberOfLogins" ) = select("login" ).in("logins" ) / filter(clause("login.user" ) == "user._key" ) / collect().with("COUNT" ).in("numLogins" ) / yield("numLogins" ) ) / filter(clause("numberOfLogins" ) > 50 ) / update("user" ).with( assign("isImportantUser" , 1 ) .assign("dateBecameImportant" , "date" ) .assign("uncles_name" , std ::string ("tash" )) ).in("users" )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 LET date = DATE_NOW() FOR user IN users FILTER user.isImportantUser == null LET numberOfLogins = ( FOR login IN logins FILTER login.user == user._key COLLECT WITH COUNT INTO numLogins RETURN numLogins ) FILTER numberOfLogins > 50 UPDATE user WITH { isImportantUser: 1, dateBecameImportant: date, uncles_name: "tash" } IN users
replace 1 2 3 4 5 6 replace(nlohmann::json{ {"_key" , 1234 } }).with({ {"name" , "tash" }, {"uncles_name" , "tash" } }).in("students" )
1 2 3 4 5 REPLACE {"_key":1234} WITH { "name":"tash", "uncles_name":"tash" } IN students
remove 1 erase(assign("_key" , "1" )).in("students" )
1 REMOVE {_key: 1} IN students
upsert 1 2 3 4 5 6 7 8 9 upsert(nlohmann::json{ {"name" , "tokai" } }).insert({ {"name" , "tokai" }, {"fathers_name" , "tokai" } }).update({ {"name" , "tokai" }, {"fathers_name" , "tokai" } }).in("students" )
1 2 3 4 UPSERT {"name":"tokai"} INSERT {"fathers_name":"tokai","name":"tokai"} UPDATE {"fathers_name":"tokai","name":"tokai"} IN students
create graph 1 2 3 4 5 auto graph = ddl::graph_definition("corpus" ) .add_edge_definition(ddl::edge_definition("StructuralE" ).add_from("Word" ).add_to("Word" ).add_to("Sentence" )) .add_edge_definition(ddl::edge_definition("WNeighbourhoodE" ).add_from("Word" ).add_to("Word" )) .add_edge_definition(ddl::edge_definition("InstanceE" ).add_from("Word" ).add_to("Vocabulary" )); query("_api/gharial" , graph.json().dump());
create aql function 1 2 3 4 5 6 7 8 9 10 11 std ::string function_str = R"( function(p1, p2){ // function body } )" ;auto fnc = nlohmann::json({ {"name" , "NS::FNAME" }, {"code" , function_str}, {"isDeterministic" , true } }); query("_api/aqlfunction" , fnc.dump());