1
0
Fork 0
arangodb/Doxygen/doc/HttpCursor.html

397 lines
16 KiB
HTML

<html><head><title>ArangoDB Manual</title> <style media="screen" type="text/css" style="display:none">body{background-color:white;font:13px Helvetica,arial,freesans,clean,sans-serif;line-height:1.4;color:#333;}#access{font-size:16px;margin-left:12px;display:block;margin-left:10px;margin-right:10px;background-color:#F3F1EE!important;}#access a{border-right:1px solid #DBDEDF;color:#A49F96;display:block;line-height:38px;padding:0 10px;text-decoration:none;}#navigation ul{text-transform:uppercase;list-style:none;margin:0;}#navigation li{float:left;position:relative;}#container{width:920px;margin:0 auto;}a{color:#4183C4;text-decoration:none;}.contents h2{font-size:24px;border-bottom:1px solid #CCC;color:black;}.contents h1{font-size:33px;border-bottom:1px solid #CCC;color:black;}.clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;visibility:hidden;}/**/ *:first-child+html .clearfix{min-height:0;}/**/ * html .clearfix{height:1%;}</style></head><body><div id="container"><img src="images/logo_arangodb.png" width="397" height="67" alt="ArangoDB"><div id="access" role="navigation"><div id="navigation"><ul id="menu-ahome" class="menu"><li><a href="Home.html">Table of contents</a></li> <li><a href="http://www.arangodb.org">ArangoDB homepage</a></li></ul></div><div class="clearfix"></div></div><div>
<!-- Generated by Doxygen 1.7.5.1 -->
</div>
<div class="header">
<div class="headertitle">
<h1>HTTP Interface for AQL Query Cursors </h1> </div>
</div>
<div class="contents">
<div class="textblock"><p>This is an introduction to ArangoDB's Http interface for Queries. Results of AQL and simple queries are returned as cursors in order to batch the communication between server and client. Each call returns a number of documents in a batch and an indication, if the current batch has been the final batch. Depending on the query, the total number of documents in the result set might or might not be known in advance. In order to free server resources the client should delete the cursor as soon as it is no longer needed.</p>
<hr/>
<ul>
<li>
<a class="el" href="HttpCursor.html">HTTP Interface for AQL Query Cursors</a> <ul>
<li>
<a class="el" href="HttpCursor.html#HttpCursorResults">Retrieving query results</a> <ul>
<li>
<a class="el" href="HttpCursor.html#HttpCursorResultsSingle">Single roundtrip</a> </li>
<li>
<a class="el" href="HttpCursor.html#HttpCursorResultsCursor">Using a Cursor</a> </li>
</ul>
</li>
<li>
<a class="el" href="HttpCursor.html#HttpCursorHttp">Accessing Cursors via HTTP</a> <ul>
<li>
<a class="el" href="HttpCursor.html#HttpCursorPost">POST /_api/cursor</a> </li>
<li>
<a class="el" href="HttpCursor.html#HttpCursorPostQuery">POST /_api/query</a> </li>
<li>
<a class="el" href="HttpCursor.html#HttpCursorPut">PUT /_api/cursor/cursor-identifier</a> </li>
<li>
<a class="el" href="HttpCursor.html#HttpCursorDelete">DELETE /_api/cursor/cursor-identifier</a> </li>
</ul>
</li>
</ul>
</li>
</ul>
<hr/>
To run a select query, the query details need to be shipped from the client to the server via a HTTP POST request.</p>
<h2><a class="anchor" id="HttpCursorResults"></a>
Retrieving query results</h2>
<p>Select queries are executed on-the-fly on the server and the result set will be returned back to the client.</p>
<p>There are two ways the client can get the result set from the server:</p>
<ul>
<li>in a single roundtrip</li>
</ul>
<ul>
<li>using a cursor</li>
</ul>
<h3><a class="anchor" id="HttpCursorResultsSingle"></a>
Single roundtrip</h3>
<p>The server will only transfer a certain number of result documents back to the client in one roundtrip. This number is controllable by the client by setting the <code>batchSize</code> attribute when issueing the query.</p>
<p>If the complete result can be transferred to the client in one go, the client does not need to issue any further request. The client can check whether it has retrieved the complete result set by checking the <code>hasMore</code> attribute of the result set. If it is set to false, then the client has fetched the complete result set from the server.</p>
<p><b>Examples</b><br/>
</p>
<div class="fragment"><pre class="fragment">&gt; curl --data @- -X POST --dump - http://localhost:8529/_api/cursor
{ "query" : "FOR u IN users LIMIT 2 RETURN u", "count" : true, "batchSize" : 2 }
HTTP/1.1 201 Created
content-type: application/json
{
"hasMore": false,
"error": false,
"result": [
{
"n": 0,
"_rev": 21030455,
"_id": "19588663/21030455"
},
{
"n": 1,
"_rev": 21030455,
"_id": "19588663/21030455"
}
],
"code": 201,
"count": 2
}
</pre></div><h3><a class="anchor" id="HttpCursorResultsCursor"></a>
Using a Cursor</h3>
<p>If the result set contains more documents than should be transferred in a single roundtrip (i.e. as set via the <code>batchSize</code> attribute), the server will return the first few documents and create a temporary cursor. The cursor identifier will also be returned to the client. The server will put the cursor identifier in the <code>id</code> attribute of the response object. Furthermore, the <code>hasMore</code> attribute of the response object will be set to <code>true</code>. This is an indication for the client that there are additional results to fetch from the server.</p>
<p><b>Examples</b><br/>
</p>
<p>Create and extract first batch:</p>
<div class="fragment"><pre class="fragment">&gt; curl --data @- -X POST --dump - http://localhost:8529/_api/cursor
{ "query" : "FOR u IN users LIMIT 5 RETURN u", "count" : true, "batchSize" : 2 }
HTTP/1.1 201 Created
content-type: application/json
{
"hasMore": true,
"error": false,
"id": 26011191,
"result": [
{
"n": 0,
"_rev": 25880119,
"_id": "23914039/25880119"
},
{
"n": 1,
"_rev": 25880119,
"_id": "23914039/25880119"
}
],
"code": 201,
"count": 5
}
</pre></div><p>Extract next batch, still have more:</p>
<div class="fragment"><pre class="fragment">&gt; curl -X PUT --dump - http://localhost:8529/_api/cursor/26011191
HTTP/1.1 200 OK
content-type: application/json
{
"hasMore": true,
"error": false,
"id": 26011191,
"result": [
{
"n": 2,
"_rev": 25880119,
"_id": "23914039/25880119"
},
{
"n": 3,
"_rev": 25880119,
"_id": "23914039/25880119"
}
],
"code": 200,
"count": 5
}
</pre></div><p>Extract next batch, done:</p>
<div class="fragment"><pre class="fragment">&gt; curl -X PUT --dump - http://localhost:8529/_api/cursor/26011191
HTTP/1.1 200 OK
content-type: application/json
{
"hasMore": false,
"error": false,
"result": [
{
"n": 4,
"_rev": 25880119,
"_id": "23914039/25880119"
}
],
"code": 200,
"count": 5
}
</pre></div><p>Do not do this:</p>
<div class="fragment"><pre class="fragment">&gt; curl -X PUT --dump - http://localhost:8529/_api/cursor/26011191
HTTP/1.1 400 Bad Request
content-type: application/json
{
"errorNum": 1600,
"errorMessage": "cursor not found: disposed or unknown cursor",
"error": true,
"code": 400
}
</pre></div><h2><a class="anchor" id="HttpCursorHttp"></a>
Accessing Cursors via HTTP</h2>
<p><a class="anchor" id="HttpCursorPost"></a> <hr/>
<em>POST /_api/cursor</em> (creates a cursor)<hr/>
<br/>
<code><b>POST /_api/cursor</b></code></p>
<p>The query details include the query string plus optional query options and bind parameters. These values need to be passed in a JSON representation in the body of the POST request.</p>
<p>The following attributes can be used inside the JSON object:</p>
<ul>
<li><code>query</code>: contains the query string to be executed (mandatory)</li>
</ul>
<ul>
<li><code>count</code>: boolean flag that indicates whether the number of documents found should be returned as "count" attribute in the result set (optional). Calculating the "count" attribute might have a performance penalty for some queries so this option is turned off by default.</li>
</ul>
<ul>
<li><code>batchSize</code>: maximum number of result documents to be transferred from the server to the client in one roundtrip (optional). If this attribute is not set, a server-controlled default value will be used.</li>
</ul>
<ul>
<li><code>bindVars</code>: key/value list of bind parameters (optional).</li>
</ul>
<p>If the result set can be created by the server, the server will respond with <code>HTTP 201</code>. The body of the response will contain a JSON object with the result set.</p>
<p>The JSON object has the following properties:</p>
<ul>
<li><code>error</code>: boolean flag to indicate that an error occurred (<code>false</code> in this case)</li>
</ul>
<ul>
<li><code>code</code>: the HTTP status code</li>
</ul>
<ul>
<li><code>result</code>: an array of result documents (might be empty if query has no results)</li>
</ul>
<ul>
<li><code>hasMore</code>: a boolean indicator whether there are more results available on the server</li>
</ul>
<ul>
<li><code>count</code>: the total number of result documents available (only available if the query was executed with the <code>count</code> attribute set.</li>
</ul>
<ul>
<li><code>id</code>: id of temporary cursor created on the server (optional, see above)</li>
</ul>
<p>If the JSON representation is malformed or the query specification is missing from the request, the server will respond with <code>HTTP 400</code>.</p>
<p>The body of the response will contain a JSON object with additional error details. The object has the following attributes:</p>
<ul>
<li><code>error</code>: boolean flag to indicate that an error occurred (<code>true</code> in this case)</li>
</ul>
<ul>
<li><code>code</code>: the HTTP status code</li>
</ul>
<ul>
<li><code>errorNum</code>: the server error number</li>
</ul>
<ul>
<li><code>errorMessage</code>: a descriptive error message</li>
</ul>
<p>If the query specification is complete, the server will process the query. If an error occurs during query processing, the server will respond with <code>HTTP 400</code>. Again, the body of the response will contain details about the error.</p>
<p>A list of query errors can be found <a class="el" href="ArangoErrors.html">Error codes and meanings</a> here.</p>
<p><b>Examples</b><br/>
</p>
<p>Executes a query and extract the result in a single go:</p>
<div class="fragment"><pre class="fragment">&gt; curl --data @- -X POST --dump - http://localhost:8529/_api/cursor
{ "query" : "FOR u IN users LIMIT 2 RETURN u", "count" : true, "batchSize" : 2 }
HTTP/1.1 201 Created
content-type: application/json
{
"hasMore": false,
"error": false,
"result": [
{
"n": 0,
"_rev": 21030455,
"_id": "19588663/21030455"
},
{
"n": 1,
"_rev": 21030455,
"_id": "19588663/21030455"
}
],
"code": 201,
"count": 2
}
</pre></div><p>Bad queries:</p>
<div class="fragment"><pre class="fragment">&gt; curl -X POST --dump - http://localhost:8529/_api/cursor
HTTP/1.1 400 Bad Request
content-type: application/json
{
"errorNum": 1503,
"code": 400,
"error": true,
"errorMessage": "query specification invalid"
}
</pre></div><div class="fragment"><pre class="fragment">&gt; curl --data @- -X POST --dump - http://localhost:8529/_api/cursor
{ "query" : "FOR u IN unknowncollection LIMIT 2 RETURN u.n", "count" : true, "bindVars" : {}, "batchSize" : 2 }
HTTP/1.1 400 Bad Request
content-type: application/json
{
"code": 400,
"error": true,
"errorMessage": "unable to open collection '%s': unable to open collection 'unknowncollection'",
"errorNum": 1510
}
</pre></div> <p><a class="anchor" id="HttpCursorPostQuery"></a> <hr/>
<em>POST /_api/query</em> (parses a query)<hr/>
<br/>
<code><b>POST /_api/query</b></code></p>
<p>To validate a query string without executing it, the query string can be passed to the server via an HTTP POST request.</p>
<p>These query string needs to be passed in the attribute <code>query</code> of a JSON object as the body of the POST request.</p>
<p>If the query is valid, the server will respond with <code>HTTP 200</code> and return the names of the bind parameters it found in the query (if any) in the <code>"bindVars"</code> attribute of the response.</p>
<p>The server will respond with <code>HTTP 400</code> in case of a malformed request, or if the query contains a parse error. The body of the response will contain the error details embedded in a JSON object.</p>
<p><b>Examples</b><br/>
</p>
<p>Valid query:</p>
<div class="fragment"><pre class="fragment">&gt; curl --data @- -X POST --dump - http://localhost:8529/_api/query
{ "query" : "FOR u IN users FILTER u.name == @name LIMIT 2 RETURN u.n" }
HTTP/1.1 200 OK
content-type: application/json
{
"error": false,
"bindVars": [
"name"
],
"code": 200
}
</pre></div><p>Invalid query:</p>
<div class="fragment"><pre class="fragment">&gt; curl --data @- -X POST --dump - http://localhost:8529/_api/query
{ "query" : "FOR u IN users FILTER u.name = @name LIMIT 2 RETURN u.n" }
HTTP/1.1 400 Bad Request
content-type: application/json
{
"errorNum": 1501,
"errorMessage": "parse error: %s: parse error: 1:29 syntax error, unexpected assignment near ' = @name LIMIT 2 RETURN u.n'",
"error": true,
"code": 400
}
</pre></div> <p><a class="anchor" id="HttpCursorPut"></a> <hr/>
<em>PUT /_api/cursor</em> (reads next batch from a cursor)<hr/>
<br/>
<code><b>PUT /_api/cursor/<em>cursor-identifier</em></b></code></p>
<p>If the cursor is still alive, returns an object with the following attributes.</p>
<ul>
<li><code>id</code>: the <em>cursor-identifier</em></li>
<li><code>result</code>: a list of documents for the current batch</li>
<li><code>hasMore</code>: <code>false</code> if this was the last batch</li>
<li><code>count</code>: if present the total number of elements</li>
</ul>
<p>Note that even if <code>hasMore</code> returns <code>true</code>, the next call might still return no documents. If, however, <code>hasMore</code> is <code>false</code>, then the cursor is exhausted. Once the <code>hasMore</code> attribute has a value of <code>false</code>, the client can stop.</p>
<p>The server will respond with <code>HTTP 200</code> in case of success. If the cursor identifier is ommitted or somehow invalid, the server will respond with <code>HTTP 404</code>.</p>
<p><b>Examples</b><br/>
</p>
<p>Valid request for next batch:</p>
<div class="fragment"><pre class="fragment">&gt; curl -X PUT --dump - http://localhost:8529/_api/cursor/26011191
HTTP/1.1 200 OK
content-type: application/json
{
"hasMore": true,
"error": false,
"id": 26011191,
"result": [
{
"n": 2,
"_rev": 25880119,
"_id": "23914039/25880119"
},
{
"n": 3,
"_rev": 25880119,
"_id": "23914039/25880119"
}
],
"code": 200,
"count": 5
}
</pre></div><p>Missing identifier</p>
<div class="fragment"><pre class="fragment">&gt; curl -X PUT --dump - http://localhost:8529/_api/cursor
HTTP/1.1 400 Bad Request
content-type: application/json
{
"code": 400,
"errorMessage": "bad parameter",
"errorNum": 400,
"error": true
}
</pre></div><p>Unknown identifier</p>
<div class="fragment"><pre class="fragment">&gt; curl -X PUT --dump - http://localhost:8529/_api/cursor/123456
HTTP/1.1 400 Bad Request
content-type: application/json
{
"code": 400,
"errorNum": 1600,
"error": true,
"errorMessage": "cursor not found: disposed or unknown cursor"
}
</pre></div> <p><a class="anchor" id="HttpCursorDelete"></a> <hr/>
<em>DELETE /_api/cursor</em> (deletes a cursor)<hr/>
<br/>
<code><b>DELETE /_api/cursor/<em>cursor-identifier</em></b></code></p>
<p>Deletes the cursor and frees the resources associated with it.</p>
<p>The cursor will automatically be destroyed on the server when the client has retrieved all documents from it. The client can also explicitly destroy the cursor at any earlier time using an HTTP DELETE request. The cursor id must be included as part of the URL.</p>
<p>In case the server is aware of the cursor, it will respond with <code>HTTP 202</code>. Otherwise, it will respond with <code>404</code>.</p>
<p>Cursors that have been explicitly destroyed must not be used afterwards. If a cursor is used after it has been destroyed, the server will respond with <code>HTTP 404</code> as well.</p>
<p>Note: the server will also destroy abandoned cursors automatically after a certain server-controlled timeout to avoid resource leakage.</p>
<p><b>Examples</b><br/>
</p>
<div class="fragment"><pre class="fragment">&gt; curl -X DELETE --dump - http://localhost:8529/_api/cursor/8679702
HTTP/1.1 202 Accepted
content-type: application/json
{
"code": 202,
"id": "8679702",
"error": false
}
</pre></div> </div></div>
</div></body></html>