Dave
Dave

Reputation: 2741

How to specify the database in an ArangoDb AQL query?

If have multiple databases defined on a particular ArangoDB server, how do I specify the database I'd like an AQL query to run against?

Running the query through the REST endpoint that includes the db name (substituted into [DBNAME] below) ie:

/_db/[DBNAME]/_api/cursor

doesn't seem to work. The error message says 'unknown path /_db/[DBNAME]/_api/cursor'

Is this something I have to specify in the query itself?

Also: The query I'm trying to run is:

FOR col in COLLECTIONS() RETURN col.name

Fwiw, I haven't found a way to set the "current" database through the REST API. Also, I'm accessing the REST API from C++ using fuerte.

Upvotes: 2

Views: 545

Answers (2)

gamedev8
gamedev8

Reputation: 61

The docs aren't very helpful right now, so just incase someone is looking for a more complete example, then please consider the following code.

EventLoopService eventLoopService;
// adjust the connection for your environment!
std::shared_ptr<Connection> conn = ConnectionBuilder().endpoint("http://localhost:8529")
        .authenticationType(AuthenticationType::Basic)
        .user(?)      // enter a user with access
        .password(?)  // enter the password
        .connect(eventLoopService);

// create the request
std::unique_ptr<Request> request = createRequest(RestVerb::Post, ContentType::VPack);

// enter the database name (ensure the user has access)
request->header.database = ?;

// API endpoint to submit AQL queries
request->header.path = "/_api/cursor";

// Create a payload to be submitted to the API endpoint
VPackBuilder builder;
builder.openObject();
// here is your query
builder.add("query", VPackValue("for col in collections() return col.name"));
builder.close();

// add the payload to the request
request->addVPack(builder.slice());

// send the request (blocking)
std::unique_ptr<Response> response = conn->sendRequest(std::move(request));

// check the response code - it should be 201
unsigned int statusCode = response->statusCode();

// slice has the response data
VPackSlice slice = response->slices().front();

std::cout << slice.get("result").toJson() << std::endl;

Upvotes: 0

Dave
Dave

Reputation: 2741

Tom Regner deserves primary credit here for prompting the enquiry that produced this answer. I am posting my findings here as an answer to help others who might run into this.

I don't know if this is a fuerte bug, shortcoming or just an api caveat that wasn't clear to me... BUT...

In order for the '/_db/[DBNAME/' prefix in an endpoint (eg full endpoint '/_db/[DBNAME/_api/cursor') to be registered and used in the header of a ::arangodb::fuerte::Request, it is NOT sufficient (as of arangodb 3.5.3 and the fuerte version available at the time of this answer) to simply call:

std::unique_ptr<fuerte::Request> request;
const char *endpoint = "/_db/[DBNAME/_api/cursor";
request = fuerte::createRequest(fuerte::RestVerb::Post,endpoint);
// and adding any arguments to the request using a VPackBuilder...
// in this case the query (omitted)

To have the database name included as part of such a request, you must additionally call the following:

request->header.parseArangoPath(endpoint);

Failure to do so seems to result in an error about an 'unknown path'.

Note 1: Simply setting the database member variable, ie

request->header.database = "[DBNAME]";

does not work.

Note 2: that operations without the leading '/_db/[DBNAME]/' prefix, seem to work fine using the 'current' database. (which at least for me, seems to be stuck at '_system' since as far as I can tell, there doesn't seem to be an endpoint to change this via the HTTP REST Api.)

Upvotes: 3

Related Questions