blob: 053f0f307b9228270249ca5a71a2d215da82b81b [file] [log] [blame]
Ian Maxone2b799e2015-11-24 18:20:03 -08001<!DOCTYPE html>
2<!--
3 | Generated by Apache Maven Doxia at 2015-11-24
4 | Rendered using Apache Maven Fluido Skin 1.3.0
5-->
6<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <meta charset="UTF-8" />
9 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10 <meta name="Date-Revision-yyyymmdd" content="20151124" />
11 <meta http-equiv="Content-Language" content="en" />
12 <title>AsterixDB &#x2013; AsterixDB 101: An ADM and AQL Primer</title>
13 <link rel="stylesheet" href="../css/apache-maven-fluido-1.3.0.min.css" />
14 <link rel="stylesheet" href="../css/site.css" />
15 <link rel="stylesheet" href="../css/print.css" media="print" />
16
17
18 <script type="text/javascript" src="../js/apache-maven-fluido-1.3.0.min.js"></script>
19
20
21
22<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
23 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
24 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
25 })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
26
27 ga('create', 'UA-41536543-1', 'uci.edu');
28 ga('send', 'pageview');</script>
29
30 </head>
31 <body class="topBarDisabled">
32
33
34
35
36 <div class="container-fluid">
37 <div id="banner">
38 <div class="pull-left">
39 <a href="http://asterixdb.apache.org/" id="bannerLeft">
40 <img src="../images/asterixlogo.png" alt="AsterixDB"/>
41 </a>
42 </div>
43 <div class="pull-right"> </div>
44 <div class="clear"><hr/></div>
45 </div>
46
47 <div id="breadcrumbs">
48 <ul class="breadcrumb">
49
50
51 <li id="publishDate">Last Published: 2015-11-24</li>
52
53
54
55 <li id="projectVersion" class="pull-right">Version: 0.8.7-incubating</li>
56
57 <li class="divider pull-right">|</li>
58
59 <li class="pull-right"> <a href="../index.html" title="Documentation Home">
60 Documentation Home</a>
61 </li>
62
63 </ul>
64 </div>
65
66
67 <div class="row-fluid">
68 <div id="leftColumn" class="span3">
69 <div class="well sidebar-nav">
70
71
72 <ul class="nav nav-list">
73 <li class="nav-header">Documentation</li>
74
75 <li>
76
77 <a href="../install.html" title="Installing and Managing AsterixDB using Managix">
78 <i class="none"></i>
79 Installing and Managing AsterixDB using Managix</a>
80 </li>
81
82 <li>
83
84 <a href="../yarn.html" title="Deploying AsterixDB using YARN">
85 <i class="none"></i>
86 Deploying AsterixDB using YARN</a>
87 </li>
88
89 <li class="active">
90
91 <a href="#"><i class="none"></i>AsterixDB 101: An ADM and AQL Primer</a>
92 </li>
93
94 <li>
95
96 <a href="../aql/primer-sql-like.html" title="AsterixDB 101: An ADM and AQL Primer (For SQL Fans)">
97 <i class="none"></i>
98 AsterixDB 101: An ADM and AQL Primer (For SQL Fans)</a>
99 </li>
100
101 <li>
102
103 <a href="../aql/js-sdk.html" title="AsterixDB Javascript SDK">
104 <i class="none"></i>
105 AsterixDB Javascript SDK</a>
106 </li>
107
108 <li>
109
110 <a href="../aql/datamodel.html" title="Asterix Data Model (ADM)">
111 <i class="none"></i>
112 Asterix Data Model (ADM)</a>
113 </li>
114
115 <li>
116
117 <a href="../aql/manual.html" title="Asterix Query Language (AQL)">
118 <i class="none"></i>
119 Asterix Query Language (AQL)</a>
120 </li>
121
122 <li>
123
124 <a href="../aql/functions.html" title="AQL Functions">
125 <i class="none"></i>
126 AQL Functions</a>
127 </li>
128
129 <li>
130
131 <a href="../aql/allens.html" title="AQL Allen's Relations Functions">
132 <i class="none"></i>
133 AQL Allen's Relations Functions</a>
134 </li>
135
136 <li>
137
138 <a href="../aql/similarity.html" title="AQL Support of Similarity Queries">
139 <i class="none"></i>
140 AQL Support of Similarity Queries</a>
141 </li>
142
143 <li>
144
145 <a href="../aql/externaldata.html" title="Accessing External Data">
146 <i class="none"></i>
147 Accessing External Data</a>
148 </li>
149
150 <li>
151
152 <a href="../feeds/tutorial.html" title="Support for Data Ingestion in AsterixDB">
153 <i class="none"></i>
154 Support for Data Ingestion in AsterixDB</a>
155 </li>
156
157 <li>
158
159 <a href="../udf.html" title="Support for User Defined Functions in AsterixDB">
160 <i class="none"></i>
161 Support for User Defined Functions in AsterixDB</a>
162 </li>
163
164 <li>
165
166 <a href="../aql/filters.html" title="Filter-Based LSM Index Acceleration">
167 <i class="none"></i>
168 Filter-Based LSM Index Acceleration</a>
169 </li>
170
171 <li>
172
173 <a href="../api.html" title="HTTP API to AsterixDB">
174 <i class="none"></i>
175 HTTP API to AsterixDB</a>
176 </li>
177 </ul>
178
179
180
181 <hr class="divider" />
182
183 <div id="poweredBy">
184 <div class="clear"></div>
185 <div class="clear"></div>
186 <div class="clear"></div>
187 <a href="https://code.google.com/p/hyracks/" title="Hyracks" class="builtBy">
188 <img class="builtBy" alt="Hyracks" src="../images/hyrax_ts.png" />
189 </a>
190 </div>
191 </div>
192 </div>
193
194
195 <div id="bodyColumn" class="span9" >
196
197 <!-- ! Licensed to the Apache Software Foundation (ASF) under one
198 ! or more contributor license agreements. See the NOTICE file
199 ! distributed with this work for additional information
200 ! regarding copyright ownership. The ASF licenses this file
201 ! to you under the Apache License, Version 2.0 (the
202 ! "License"); you may not use this file except in compliance
203 ! with the License. You may obtain a copy of the License at
204 !
205 ! http://www.apache.org/licenses/LICENSE-2.0
206 !
207 ! Unless required by applicable law or agreed to in writing,
208 ! software distributed under the License is distributed on an
209 ! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
210 ! KIND, either express or implied. See the License for the
211 ! specific language governing permissions and limitations
212 ! under the License.
213 ! --><h1>AsterixDB 101: An ADM and AQL Primer</h1>
214<div class="section">
215<h2><a name="Welcome_to_AsterixDB"></a>Welcome to AsterixDB!</h2>
216<p>This document introduces the main features of AsterixDB&#x2019;s data model (ADM) and query language (AQL) by example. The example is a simple scenario involving (synthetic) sample data modeled after data from the social domain. This document describes a set of sample ADM datasets, together with a set of illustrative AQL queries, to introduce you to the &#x201c;AsterixDB user experience&#x201d;. The complete set of steps required to create and load a handful of sample datasets, along with runnable queries and the expected results for each query, are included.</p>
217<p>This document assumes that you are at least vaguely familiar with AsterixDB and why you might want to use it. Most importantly, it assumes you already have a running instance of AsterixDB and that you know how to query it using AsterixDB&#x2019;s basic web interface. For more information on these topics, you should go through the steps in <a href="../install.html">Installing Asterix Using Managix</a> before reading this document and make sure that you have a running AsterixDB instance ready to go. To get your feet wet, you should probably start with a simple local installation of AsterixDB on your favorite machine, accepting all of the default settings that Managix offers. Later you can graduate to trying AsterixDB on a cluster, its real intended home (since it targets Big Data). (Note: With the exception of specifying the correct locations where you put the source data for this example, there should no changes needed in your ADM or AQL statements to run the examples locally and/or to run them on a cluster when you are ready to take that step.)</p>
218<p>As you read through this document, you should try each step for yourself on your own AsterixDB instance. Once you have reached the end, you will be fully armed and dangerous, with all the basic AsterixDB knowledge that you&#x2019;ll need to start down the path of modeling, storing, and querying your own semistructured data.</p>
219<p>&#x2014;-</p></div>
220<div class="section">
221<h2><a name="ADM:_Modeling_Semistructed_Data_in_AsterixDB"></a>ADM: Modeling Semistructed Data in AsterixDB</h2>
222<p>In this section you will learn all about modeling Big Data using ADM, the data model of the AsterixDB BDMS.</p>
223<div class="section">
224<h3><a name="Dataverses_Datatypes_and_Datasets"></a>Dataverses, Datatypes, and Datasets</h3>
225<p>The top-level organizing concept in the AsterixDB world is the <i>dataverse</i>. A dataverse&#x2014;short for &#x201c;data universe&#x201d;&#x2014;is a place (similar to a database in a relational DBMS) in which to create and manage the types, datasets, functions, and other artifacts for a given AsterixDB application. When you start using an AsterixDB instance for the first time, it starts out &#x201c;empty&#x201d;; it contains no data other than the AsterixDB system catalogs (which live in a special dataverse called the Metadata dataverse). To store your data in AsterixDB, you will first create a dataverse and then you use it for the <i>datatypes</i> and <i>datasets</i> for managing your own data. A datatype tells AsterixDB what you know (or more accurately, what you want it to know) a priori about one of the kinds of data instances that you want AsterixDB to hold for you. A dataset is a collection of data instances of a datatype, and AsterixDB makes sure that the data instances that you put in it conform to its specified type. Since AsterixDB targets semistructured data, you can use <i>open</i> datatypes and tell it as little or as much as you wish about your data up front; the more you tell it up front, the less information it will have to store repeatedly in the individual data instances that you give it. Instances of open datatypes are permitted to have additional content, beyond what the datatype says, as long as they at least contain the information prescribed by the datatype definition. Open typing allows data to vary from one instance to another and it leaves wiggle room for application evolution in terms of what might need to be stored in the future. If you want to restrict data instances in a dataset to have only what the datatype says, and nothing extra, you can define a <i>closed</i> datatype for that dataset and AsterixDB will keep users from storing objects that have extra data in them. Datatypes are open by default unless you tell AsterixDB otherwise. Let&#x2019;s put these concepts to work</p>
226<p>Our little sample scenario involves hypothetical information about users of two popular social networks, Facebook and Twitter, and their messages. We&#x2019;ll start by defining a dataverse called &#x201c;TinySocial&#x201d; to hold our datatypes and datasets. The AsterixDB data model (ADM) is essentially a superset of JSON&#x2014;it&#x2019;s what you get by extending JSON with more data types and additional data modeling constructs borrowed from object databases. The following is how we can create the TinySocial dataverse plus a set of ADM types for modeling Twitter users, their Tweets, Facebook users, their users&#x2019; employment information, and their messages. (Note: Keep in mind that this is just a tiny and somewhat silly example intended for illustrating some of the key features of AsterixDB. :-))</p>
227
228<div class="source">
229<div class="source">
230<pre> drop dataverse TinySocial if exists;
231 create dataverse TinySocial;
232 use dataverse TinySocial;
233
234 create type TwitterUserType as open {
235 screen-name: string,
236 lang: string,
237 friends_count: int64,
238 statuses_count: int64,
239 name: string,
240 followers_count: int64
241 }
242
243 create type TweetMessageType as closed {
244 tweetid: string,
245 user: TwitterUserType,
246 sender-location: point?,
247 send-time: datetime,
248 referred-topics: {{ string }},
249 message-text: string
250 }
251
252 create type EmploymentType as open {
253 organization-name: string,
254 start-date: date,
255 end-date: date?
256 }
257
258 create type FacebookUserType as closed {
259 id: int64,
260 alias: string,
261 name: string,
262 user-since: datetime,
263 friend-ids: {{ int64 }},
264 employment: [EmploymentType]
265 }
266
267 create type FacebookMessageType as closed {
268 message-id: int64,
269 author-id: int64,
270 in-response-to: int64?,
271 sender-location: point?,
272 message: string
273 }
274</pre></div></div>
275<p>The first three lines above tell AsterixDB to drop the old TinySocial dataverse, if one already exists, and then to create a brand new one and make it the focus of the statements that follow. The first type creation statement creates a datatype for holding information about Twitter users. It is a record type with a mix of integer and string data, very much like a (flat) relational tuple. The indicated fields are all mandatory, but because the type is open, additional fields are welcome. The second statement creates a datatype for Twitter messages; this shows how to specify a closed type. Interestingly (based on one of Twitter&#x2019;s APIs), each Twitter message actually embeds an instance of the sending user&#x2019;s information (current as of when the message was sent), so this is an example of a nested record in ADM. Twitter messages can optionally contain the sender&#x2019;s location, which is modeled via the sender-location field of spatial type <i>point</i>; the question mark following the field type indicates its optionality. An optional field is like a nullable field in SQL&#x2014;it may be present or missing, but when it&#x2019;s present, its data type will conform to the datatype&#x2019;s specification. The send-time field illustrates the use of a temporal primitive type, <i>datetime</i>. Lastly, the referred-topics field illustrates another way that ADM is richer than the relational model; this field holds a bag (a.k.a. an unordered list) of strings. Since the overall datatype definition for Twitter messages says &#x201c;closed&#x201d;, the fields that it lists are the only fields that instances of this type will be allowed to contain. The next two create type statements create a record type for holding information about one component of the employment history of a Facebook user and then a record type for holding the user information itself. The Facebook user type highlights a few additional ADM data model features. Its friend-ids field is a bag of integers, presumably the Facebook user ids for this user&#x2019;s friends, and its employment field is an ordered list of employment records. The final create type statement defines a type for handling the content of a Facebook message in our hypothetical social data storage scenario.</p>
276<p>Before going on, we need to once again emphasize the idea that AsterixDB is aimed at storing and querying not just Big Data, but Big <i>Semistructured</i> Data. This means that most of the fields listed in the create type statements above could have been omitted without changing anything other than the resulting size of stored data instances on disk. AsterixDB stores its information about the fields defined a priori as separate metadata, whereas the information about other fields that are &#x201c;just there&#x201d; in instances of open datatypes is stored with each instance&#x2014;making for more bits on disk and longer times for operations affected by data size (e.g., dataset scans). The only fields that <i>must</i> be specified a priori are the primary key. Indexes can be built on fields that don&#x2019;t belong to the pre-specified part of datatype&#x2019;s schema as long as their type is specified at index create time and and the <i>enforced</i> keyword is provided at the end of the index definition. (The <i>enforced</i> keyword asks the system to ensure that the indexed field or fields conform to this specified type in all of the dataset&#x2019;s record instances where they are present.) Additionally, indexed fields may be nested arbitrarily deep within a dataset&#x2019;s records as long as the nesting does not go pass through a list (be it ordered or unordered) along the way.</p></div>
277<div class="section">
278<h3><a name="Creating_Datasets_and_Indexes"></a>Creating Datasets and Indexes</h3>
279<p>Now that we have defined our datatypes, we can move on and create datasets to store the actual data. (If we wanted to, we could even have several named datasets based on any one of these datatypes.) We can do this as follows, utilizing the DDL capabilities of AsterixDB.</p>
280
281<div class="source">
282<div class="source">
283<pre> use dataverse TinySocial;
284
285 create dataset FacebookUsers(FacebookUserType)
286 primary key id;
287
288 create dataset FacebookMessages(FacebookMessageType)
289 primary key message-id;
290
291 create dataset TwitterUsers(TwitterUserType)
292 primary key screen-name;
293
294 create dataset TweetMessages(TweetMessageType)
295 primary key tweetid
296 hints(cardinality=100);
297
298 create index fbUserSinceIdx on FacebookUsers(user-since);
299 create index fbAuthorIdx on FacebookMessages(author-id) type btree;
300 create index fbSenderLocIndex on FacebookMessages(sender-location) type rtree;
301 create index fbMessageIdx on FacebookMessages(message) type keyword;
302
303 for $ds in dataset Metadata.Dataset return $ds;
304 for $ix in dataset Metadata.Index return $ix;
305</pre></div></div>
306<p>The ADM DDL statements above create four datasets for holding our social data in the TinySocial dataverse: FacebookUsers, FacebookMessages, TwitterUsers, and TweetMessages. The first statement creates the FacebookUsers data set. It specifies that this dataset will store data instances conforming to FacebookUserType and that it has a primary key which is the id field of each instance. The primary key information is used by AsterixDB to uniquely identify instances for the purpose of later lookup and for use in secondary indexes. Each AsterixDB dataset is stored (and indexed) in the form of a B+ tree on primary key; secondary indexes point to their indexed data by primary key. In AsterixDB clusters, the primary key is also used to hash-partition (a.k.a. shard) the dataset across the nodes of the cluster. The next three create dataset statements are similar. The last one illustrates an optional clause for providing useful hints to AsterixDB. In this case, the hint tells AsterixDB that the dataset definer is anticipating that the TweetMessages dataset will contain roughly 100 objects; knowing this can help AsterixDB to more efficiently manage and query this dataset. (AsterixDB does not yet gather and maintain data statistics; it will currently, abitrarily, assume a cardinality of one million objects per dataset in the absence of such an optional definition-time hint.)</p>
307<p>The create dataset statements above are followed by four more DDL statements, each of which creates a secondary index on a field of one of the datasets. The first one indexes the FacebookUsers dataset on its user-since field. This index will be a B+ tree index; its type is unspecified and <i>btree</i> is the default type. The other three illustrate how you can explicitly specify the desired type of index. In addition to btree, <i>rtree</i> and inverted <i>keyword</i> indexes are supported by AsterixDB. Indexes can also have composite keys, and more advanced text indexing is available as well (ngram(k), where k is the desired gram length).</p></div>
308<div class="section">
309<h3><a name="Querying_the_Metadata_Dataverse"></a>Querying the Metadata Dataverse</h3>
310<p>The last two statements above show how you can use queries in AQL to examine the AsterixDB system catalogs and tell what artifacts you have created. Just as relational DBMSs use their own tables to store their catalogs, AsterixDB uses its own datasets to persist descriptions of its datasets, datatypes, indexes, and so on. Running the first of the two queries above will list all of your newly created datasets, and it will also show you a full list of all the metadata datasets. (You can then explore from there on your own if you are curious) These last two queries also illustrate one other factoid worth knowing: AsterixDB allows queries to span dataverses by allowing the optional use of fully-qualified dataset names (i.e., <i>dataversename.datasetname</i>) to reference datasets that live in a dataverse other than the one that was named in the most recently executed <i>use dataverse</i> directive.</p>
311<p>&#x2014;-</p></div></div>
312<div class="section">
313<h2><a name="Loading_Data_Into_AsterixDB"></a>Loading Data Into AsterixDB</h2>
314<p>Okay, so far so good&#x2014;AsterixDB is now ready for data, so let&#x2019;s give it some data to store Our next task will be to load some sample data into the four datasets that we just defined. Here we will load a tiny set of records, defined in ADM format (a superset of JSON), into each dataset. In the boxes below you can see the actual data instances contained in each of the provided sample files. In order to load this data yourself, you should first store the four corresponding <tt>.adm</tt> files (whose URLs are indicated on top of each box below) into a filesystem directory accessible to your running AsterixDB instance. Take a few minutes to look carefully at each of the sample data sets. This will give you a better sense of the nature of the data that we are about to load and query. We should note that ADM format is a textual serialization of what AsterixDB will actually store; when persisted in AsterixDB, the data format will be binary and the data in the predefined fields of the data instances will be stored separately from their associated field name and type metadata.</p>
315<p><a href="../data/twu.adm">Twitter Users</a></p>
316
317<div class="source">
318<div class="source">
319<pre> {&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:18,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416}
320 {&quot;screen-name&quot;:&quot;ColineGeyer@63&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:121,&quot;statuses_count&quot;:362,&quot;name&quot;:&quot;Coline Geyer&quot;,&quot;followers_count&quot;:17159}
321 {&quot;screen-name&quot;:&quot;NilaMilliron_tw&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:445,&quot;statuses_count&quot;:164,&quot;name&quot;:&quot;Nila Milliron&quot;,&quot;followers_count&quot;:22649}
322 {&quot;screen-name&quot;:&quot;ChangEwing_573&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:182,&quot;statuses_count&quot;:394,&quot;name&quot;:&quot;Chang Ewing&quot;,&quot;followers_count&quot;:32136}
323</pre></div></div>
324<p><a href="../data/twm.adm">Tweet Messages</a></p>
325
326<div class="source">
327<div class="source">
328<pre> {&quot;tweetid&quot;:&quot;1&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:39339,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416},&quot;sender-location&quot;:point(&quot;47.44,80.65&quot;),&quot;send-time&quot;:datetime(&quot;2008-04-26T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;t-mobile&quot;,&quot;customization&quot;}},&quot;message-text&quot;:&quot; love t-mobile its customization is good:)&quot;}
329 {&quot;tweetid&quot;:&quot;2&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;ColineGeyer@63&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:121,&quot;statuses_count&quot;:362,&quot;name&quot;:&quot;Coline Geyer&quot;,&quot;followers_count&quot;:17159},&quot;sender-location&quot;:point(&quot;32.84,67.14&quot;),&quot;send-time&quot;:datetime(&quot;2010-05-13T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;verizon&quot;,&quot;shortcut-menu&quot;}},&quot;message-text&quot;:&quot; like verizon its shortcut-menu is awesome:)&quot;}
330 {&quot;tweetid&quot;:&quot;3&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:39339,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416},&quot;sender-location&quot;:point(&quot;29.72,75.8&quot;),&quot;send-time&quot;:datetime(&quot;2006-11-04T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;motorola&quot;,&quot;speed&quot;}},&quot;message-text&quot;:&quot; like motorola the speed is good:)&quot;}
331 {&quot;tweetid&quot;:&quot;4&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:39339,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416},&quot;sender-location&quot;:point(&quot;39.28,70.48&quot;),&quot;send-time&quot;:datetime(&quot;2011-12-26T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;sprint&quot;,&quot;voice-command&quot;}},&quot;message-text&quot;:&quot; like sprint the voice-command is mind-blowing:)&quot;}
332 {&quot;tweetid&quot;:&quot;5&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:39339,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416},&quot;sender-location&quot;:point(&quot;40.09,92.69&quot;),&quot;send-time&quot;:datetime(&quot;2006-08-04T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;motorola&quot;,&quot;speed&quot;}},&quot;message-text&quot;:&quot; can't stand motorola its speed is terrible:(&quot;}
333 {&quot;tweetid&quot;:&quot;6&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;ColineGeyer@63&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:121,&quot;statuses_count&quot;:362,&quot;name&quot;:&quot;Coline Geyer&quot;,&quot;followers_count&quot;:17159},&quot;sender-location&quot;:point(&quot;47.51,83.99&quot;),&quot;send-time&quot;:datetime(&quot;2010-05-07T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;iphone&quot;,&quot;voice-clarity&quot;}},&quot;message-text&quot;:&quot; like iphone the voice-clarity is good:)&quot;}
334 {&quot;tweetid&quot;:&quot;7&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;ChangEwing_573&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:182,&quot;statuses_count&quot;:394,&quot;name&quot;:&quot;Chang Ewing&quot;,&quot;followers_count&quot;:32136},&quot;sender-location&quot;:point(&quot;36.21,72.6&quot;),&quot;send-time&quot;:datetime(&quot;2011-08-25T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;samsung&quot;,&quot;platform&quot;}},&quot;message-text&quot;:&quot; like samsung the platform is good&quot;}
335 {&quot;tweetid&quot;:&quot;8&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:39339,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416},&quot;sender-location&quot;:point(&quot;46.05,93.34&quot;),&quot;send-time&quot;:datetime(&quot;2005-10-14T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;t-mobile&quot;,&quot;shortcut-menu&quot;}},&quot;message-text&quot;:&quot; like t-mobile the shortcut-menu is awesome:)&quot;}
336 {&quot;tweetid&quot;:&quot;9&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:39339,&quot;statuses_count&quot;:473,&quot;name&quot;:&quot;Nathan Giesen&quot;,&quot;followers_count&quot;:49416},&quot;sender-location&quot;:point(&quot;36.86,74.62&quot;),&quot;send-time&quot;:datetime(&quot;2012-07-21T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;verizon&quot;,&quot;voicemail-service&quot;}},&quot;message-text&quot;:&quot; love verizon its voicemail-service is awesome&quot;}
337 {&quot;tweetid&quot;:&quot;10&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;ColineGeyer@63&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:121,&quot;statuses_count&quot;:362,&quot;name&quot;:&quot;Coline Geyer&quot;,&quot;followers_count&quot;:17159},&quot;sender-location&quot;:point(&quot;29.15,76.53&quot;),&quot;send-time&quot;:datetime(&quot;2008-01-26T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;verizon&quot;,&quot;voice-clarity&quot;}},&quot;message-text&quot;:&quot; hate verizon its voice-clarity is OMG:(&quot;}
338 {&quot;tweetid&quot;:&quot;11&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;NilaMilliron_tw&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:445,&quot;statuses_count&quot;:164,&quot;name&quot;:&quot;Nila Milliron&quot;,&quot;followers_count&quot;:22649},&quot;sender-location&quot;:point(&quot;37.59,68.42&quot;),&quot;send-time&quot;:datetime(&quot;2008-03-09T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;iphone&quot;,&quot;platform&quot;}},&quot;message-text&quot;:&quot; can't stand iphone its platform is terrible&quot;}
339 {&quot;tweetid&quot;:&quot;12&quot;,&quot;user&quot;:{&quot;screen-name&quot;:&quot;OliJackson_512&quot;,&quot;lang&quot;:&quot;en&quot;,&quot;friends_count&quot;:445,&quot;statuses_count&quot;:164,&quot;name&quot;:&quot;Oli Jackson&quot;,&quot;followers_count&quot;:22649},&quot;sender-location&quot;:point(&quot;24.82,94.63&quot;),&quot;send-time&quot;:datetime(&quot;2010-02-13T10:10:00&quot;),&quot;referred-topics&quot;:{{&quot;samsung&quot;,&quot;voice-command&quot;}},&quot;message-text&quot;:&quot; like samsung the voice-command is amazing:)&quot;}
340</pre></div></div>
341<p><a href="../data/fbu.adm">Facebook Users</a></p>
342
343<div class="source">
344<div class="source">
345<pre> {&quot;id&quot;:1,&quot;alias&quot;:&quot;Margarita&quot;,&quot;name&quot;:&quot;MargaritaStoddard&quot;,&quot;user-since&quot;:datetime(&quot;2012-08-20T10:10:00&quot;),&quot;friend-ids&quot;:{{2,3,6,10}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Codetechno&quot;,&quot;start-date&quot;:date(&quot;2006-08-06&quot;)}]}
346 {&quot;id&quot;:2,&quot;alias&quot;:&quot;Isbel&quot;,&quot;name&quot;:&quot;IsbelDull&quot;,&quot;user-since&quot;:datetime(&quot;2011-01-22T10:10:00&quot;),&quot;friend-ids&quot;:{{1,4}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Hexviafind&quot;,&quot;start-date&quot;:date(&quot;2010-04-27&quot;)}]}
347 {&quot;id&quot;:3,&quot;alias&quot;:&quot;Emory&quot;,&quot;name&quot;:&quot;EmoryUnk&quot;,&quot;user-since&quot;:datetime(&quot;2012-07-10T10:10:00&quot;),&quot;friend-ids&quot;:{{1,5,8,9}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;geomedia&quot;,&quot;start-date&quot;:date(&quot;2010-06-17&quot;),&quot;end-date&quot;:date(&quot;2010-01-26&quot;)}]}
348 {&quot;id&quot;:4,&quot;alias&quot;:&quot;Nicholas&quot;,&quot;name&quot;:&quot;NicholasStroh&quot;,&quot;user-since&quot;:datetime(&quot;2010-12-27T10:10:00&quot;),&quot;friend-ids&quot;:{{2}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Zamcorporation&quot;,&quot;start-date&quot;:date(&quot;2010-06-08&quot;)}]}
349 {&quot;id&quot;:5,&quot;alias&quot;:&quot;Von&quot;,&quot;name&quot;:&quot;VonKemble&quot;,&quot;user-since&quot;:datetime(&quot;2010-01-05T10:10:00&quot;),&quot;friend-ids&quot;:{{3,6,10}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Kongreen&quot;,&quot;start-date&quot;:date(&quot;2010-11-27&quot;)}]}
350 {&quot;id&quot;:6,&quot;alias&quot;:&quot;Willis&quot;,&quot;name&quot;:&quot;WillisWynne&quot;,&quot;user-since&quot;:datetime(&quot;2005-01-17T10:10:00&quot;),&quot;friend-ids&quot;:{{1,3,7}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;jaydax&quot;,&quot;start-date&quot;:date(&quot;2009-05-15&quot;)}]}
351 {&quot;id&quot;:7,&quot;alias&quot;:&quot;Suzanna&quot;,&quot;name&quot;:&quot;SuzannaTillson&quot;,&quot;user-since&quot;:datetime(&quot;2012-08-07T10:10:00&quot;),&quot;friend-ids&quot;:{{6}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Labzatron&quot;,&quot;start-date&quot;:date(&quot;2011-04-19&quot;)}]}
352 {&quot;id&quot;:8,&quot;alias&quot;:&quot;Nila&quot;,&quot;name&quot;:&quot;NilaMilliron&quot;,&quot;user-since&quot;:datetime(&quot;2008-01-01T10:10:00&quot;),&quot;friend-ids&quot;:{{3}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Plexlane&quot;,&quot;start-date&quot;:date(&quot;2010-02-28&quot;)}]}
353 {&quot;id&quot;:9,&quot;alias&quot;:&quot;Woodrow&quot;,&quot;name&quot;:&quot;WoodrowNehling&quot;,&quot;user-since&quot;:datetime(&quot;2005-09-20T10:10:00&quot;),&quot;friend-ids&quot;:{{3,10}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;Zuncan&quot;,&quot;start-date&quot;:date(&quot;2003-04-22&quot;),&quot;end-date&quot;:date(&quot;2009-12-13&quot;)}]}
354 {&quot;id&quot;:10,&quot;alias&quot;:&quot;Bram&quot;,&quot;name&quot;:&quot;BramHatch&quot;,&quot;user-since&quot;:datetime(&quot;2010-10-16T10:10:00&quot;),&quot;friend-ids&quot;:{{1,5,9}},&quot;employment&quot;:[{&quot;organization-name&quot;:&quot;physcane&quot;,&quot;start-date&quot;:date(&quot;2007-06-05&quot;),&quot;end-date&quot;:date(&quot;2011-11-05&quot;)}]}
355</pre></div></div>
356<p><a href="../data/fbm.adm">Facebook Messages</a></p>
357
358<div class="source">
359<div class="source">
360<pre> {&quot;message-id&quot;:1,&quot;author-id&quot;:3,&quot;in-response-to&quot;:2,&quot;sender-location&quot;:point(&quot;47.16,77.75&quot;),&quot;message&quot;:&quot; love sprint its shortcut-menu is awesome:)&quot;}
361 {&quot;message-id&quot;:2,&quot;author-id&quot;:1,&quot;in-response-to&quot;:4,&quot;sender-location&quot;:point(&quot;41.66,80.87&quot;),&quot;message&quot;:&quot; dislike iphone its touch-screen is horrible&quot;}
362 {&quot;message-id&quot;:3,&quot;author-id&quot;:2,&quot;in-response-to&quot;:4,&quot;sender-location&quot;:point(&quot;48.09,81.01&quot;),&quot;message&quot;:&quot; like samsung the plan is amazing&quot;}
363 {&quot;message-id&quot;:4,&quot;author-id&quot;:1,&quot;in-response-to&quot;:2,&quot;sender-location&quot;:point(&quot;37.73,97.04&quot;),&quot;message&quot;:&quot; can't stand at&amp;t the network is horrible:(&quot;}
364 {&quot;message-id&quot;:5,&quot;author-id&quot;:6,&quot;in-response-to&quot;:2,&quot;sender-location&quot;:point(&quot;34.7,90.76&quot;),&quot;message&quot;:&quot; love sprint the customization is mind-blowing&quot;}
365 {&quot;message-id&quot;:6,&quot;author-id&quot;:2,&quot;in-response-to&quot;:1,&quot;sender-location&quot;:point(&quot;31.5,75.56&quot;),&quot;message&quot;:&quot; like t-mobile its platform is mind-blowing&quot;}
366 {&quot;message-id&quot;:7,&quot;author-id&quot;:5,&quot;in-response-to&quot;:15,&quot;sender-location&quot;:point(&quot;32.91,85.05&quot;),&quot;message&quot;:&quot; dislike sprint the speed is horrible&quot;}
367 {&quot;message-id&quot;:8,&quot;author-id&quot;:1,&quot;in-response-to&quot;:11,&quot;sender-location&quot;:point(&quot;40.33,80.87&quot;),&quot;message&quot;:&quot; like verizon the 3G is awesome:)&quot;}
368 {&quot;message-id&quot;:9,&quot;author-id&quot;:3,&quot;in-response-to&quot;:12,&quot;sender-location&quot;:point(&quot;34.45,96.48&quot;),&quot;message&quot;:&quot; love verizon its wireless is good&quot;}
369 {&quot;message-id&quot;:10,&quot;author-id&quot;:1,&quot;in-response-to&quot;:12,&quot;sender-location&quot;:point(&quot;42.5,70.01&quot;),&quot;message&quot;:&quot; can't stand motorola the touch-screen is terrible&quot;}
370 {&quot;message-id&quot;:11,&quot;author-id&quot;:1,&quot;in-response-to&quot;:1,&quot;sender-location&quot;:point(&quot;38.97,77.49&quot;),&quot;message&quot;:&quot; can't stand at&amp;t its plan is terrible&quot;}
371 {&quot;message-id&quot;:12,&quot;author-id&quot;:10,&quot;in-response-to&quot;:6,&quot;sender-location&quot;:point(&quot;42.26,77.76&quot;),&quot;message&quot;:&quot; can't stand t-mobile its voicemail-service is OMG:(&quot;}
372 {&quot;message-id&quot;:13,&quot;author-id&quot;:10,&quot;in-response-to&quot;:4,&quot;sender-location&quot;:point(&quot;42.77,78.92&quot;),&quot;message&quot;:&quot; dislike iphone the voice-command is bad:(&quot;}
373 {&quot;message-id&quot;:14,&quot;author-id&quot;:9,&quot;in-response-to&quot;:12,&quot;sender-location&quot;:point(&quot;41.33,85.28&quot;),&quot;message&quot;:&quot; love at&amp;t its 3G is good:)&quot;}
374 {&quot;message-id&quot;:15,&quot;author-id&quot;:7,&quot;in-response-to&quot;:11,&quot;sender-location&quot;:point(&quot;44.47,67.11&quot;),&quot;message&quot;:&quot; like iphone the voicemail-service is awesome&quot;}
375</pre></div></div>
376<p>It&#x2019;s loading time! We can use AQL <i>load</i> statements to populate our datasets with the sample records shown above. The following shows how loading can be done for data stored in <tt>.adm</tt> files in your local filesystem. <i>Note:</i> You <i>MUST</i> replace the <tt>&lt;Host Name&gt;</tt> and <tt>&lt;Absolute File Path&gt;</tt> placeholders in each load statement below with valid values based on the host IP address (or host name) for the machine and directory that you have downloaded the provided <tt>.adm</tt> files to. As you do so, be very, very careful to retain the two slashes in the load statements, i.e., do not delete the two slashes that appear in front of the absolute path to your <tt>.adm</tt> files. (This will lead to a three-slash character sequence at the start of each load statement&#x2019;s file input path specification.)</p>
377
378<div class="source">
379<div class="source">
380<pre> use dataverse TinySocial;
381
382 load dataset FacebookUsers using localfs
383 ((&quot;path&quot;=&quot;&lt;Host Name&gt;://&lt;Absolute File Path&gt;/fbu.adm&quot;),(&quot;format&quot;=&quot;adm&quot;));
384
385 load dataset FacebookMessages using localfs
386 ((&quot;path&quot;=&quot;&lt;Host Name&gt;://&lt;Absolute File Path&gt;/fbm.adm&quot;),(&quot;format&quot;=&quot;adm&quot;));
387
388 load dataset TwitterUsers using localfs
389 ((&quot;path&quot;=&quot;&lt;Host Name&gt;://&lt;Absolute File Path&gt;/twu.adm&quot;),(&quot;format&quot;=&quot;adm&quot;));
390
391 load dataset TweetMessages using localfs
392 ((&quot;path&quot;=&quot;&lt;Host Name&gt;://&lt;Absolute File Path&gt;/twm.adm&quot;),(&quot;format&quot;=&quot;adm&quot;));
393</pre></div></div>
394<p>&#x2014;-</p></div>
395<div class="section">
396<h2><a name="AQL:_Querying_Your_AsterixDB_Data"></a>AQL: Querying Your AsterixDB Data</h2>
397<p>Congratulations! You now have sample social data stored (and indexed) in AsterixDB. (You are part of an elite and adventurous group of individuals. :-)) Now that you have successfully loaded the provided sample data into the datasets that we defined, you can start running queries against them.</p>
398<p>The query language for AsterixDB is AQL&#x2014;the Asterix Query Language. AQL is loosely based on XQuery, the language developed and standardized in the early to mid 2000&#x2019;s by the World Wide Web Consortium (W3C) for querying semistructured data stored in their XML format. We have tossed all of the &#x201c;XML cruft&#x201d; out of their language but retained many of its core ideas. We did this because its design was developed over a period of years by a diverse committee of smart and experienced language designers, including &#x201c;SQL people&#x201d;, &#x201c;functional programming people&#x201d;, and &#x201c;XML people&#x201d;, all of whom were focused on how to design a new query language that operates well over semistructured data. (We decided to stand on their shoulders instead of starting from scratch and revisiting many of the same issues.) Note that AQL is not SQL and not based on SQL: In other words, AsterixDB is fully &#x201c;NoSQL compliant&#x201d;. :-)</p>
399<p>In this section we introduce AQL via a set of example queries, along with their expected results, based on the data above, to help you get started. Many of the most important features of AQL are presented in this set of representative queries. You can find more details in the document on the <a href="datamodel.html">Asterix Data Model (ADM)</a>, in the <a href="manual.html">AQL Reference Manual</a>, and a complete list of built-in functions is available in the <a href="functions.html">Asterix Functions</a> document.</p>
400<p>AQL is an expression language. Even the expression 1+1 is a valid AQL query that evaluates to 2. (Try it for yourself! Okay, maybe that&#x2019;s <i>not</i> the best use of a 512-node shared-nothing compute cluster.) Most useful AQL queries will be based on the <i>FLWOR</i> (pronounced &#x201c;flower&#x201d;) expression structure that AQL has borrowed from XQuery ((<a class="externalLink" href="http://en.wikipedia.org/wiki/FLWOR))">http://en.wikipedia.org/wiki/FLWOR))</a>. The FLWOR expression syntax supports both the incremental binding (<i>for</i>) of variables to ADM data instances in a dataset (or in the result of any AQL expression, actually) and the full binding (<i>let</i>) of variables to entire intermediate results in a fashion similar to temporary views in the SQL world. FLWOR is an acronym that is short for <i>for</i>-<i>let</i>-<i>where</i>-<i>order by</i>-<i>return</i>, naming five of the most frequently used clauses from the syntax of a full AQL query. AQL also includes <i>group by</i> and <i>limit</i> clauses, as you will see shortly. Roughly speaking, for SQL afficiandos, the <i>for</i> clause in AQL is like the <i>from</i> clause in SQL, the <i>return</i> clause in AQL is like the <i>select</i> clause in SQL (but appears at the end instead of the beginning of a query), the <i>let</i> clause in AQL is like SQL&#x2019;s <i>with</i> clause, and the <i>where</i> and <i>order by</i> clauses in both languages are similar.</p>
401<p>Enough talk! Let&#x2019;s go ahead and try writing some queries and see about learning AQL by example.</p>
402<div class="section">
403<h3><a name="Query_0-A_-_Exact-Match_Lookup"></a>Query 0-A - Exact-Match Lookup</h3>
404<p>For our first query, let&#x2019;s find a Facebook user based on his or her user id. Suppose the user we want is the user whose id is 8:</p>
405
406<div class="source">
407<div class="source">
408<pre> use dataverse TinySocial;
409
410 for $user in dataset FacebookUsers
411 where $user.id = 8
412 return $user;
413</pre></div></div>
414<p>The query&#x2019;s <i>for</i> clause binds the variable <tt>$user</tt> incrementally to the data instances residing in the dataset named FacebookUsers. Its <i>where</i> clause selects only those bindings having a user id of interest, filtering out the rest. The <i>return</i> clause returns the (entire) data instance for each binding that satisfies the predicate. Since this dataset is indexed on user id (its primary key), this query will be done via a quick index lookup.</p>
415<p>The expected result for our sample data is as follows:</p>
416
417<div class="source">
418<div class="source">
419<pre> { &quot;id&quot;: 8, &quot;alias&quot;: &quot;Nila&quot;, &quot;name&quot;: &quot;NilaMilliron&quot;, &quot;user-since&quot;: datetime(&quot;2008-01-01T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 3 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Plexlane&quot;, &quot;start-date&quot;: date(&quot;2010-02-28&quot;), &quot;end-date&quot;: null } ] }
420</pre></div></div></div>
421<div class="section">
422<h3><a name="Query_0-B_-_Range_Scan"></a>Query 0-B - Range Scan</h3>
423<p>AQL, like SQL, supports a variety of different predicates. For example, for our next query, let&#x2019;s find the Facebook users whose ids are in the range between 2 and 4:</p>
424
425<div class="source">
426<div class="source">
427<pre> use dataverse TinySocial;
428
429 for $user in dataset FacebookUsers
430 where $user.id &gt;= 2 and $user.id &lt;= 4
431 return $user;
432</pre></div></div>
433<p>This query&#x2019;s expected result, also evaluable using the primary index on user id, is:</p>
434
435<div class="source">
436<div class="source">
437<pre> { &quot;id&quot;: 2, &quot;alias&quot;: &quot;Isbel&quot;, &quot;name&quot;: &quot;IsbelDull&quot;, &quot;user-since&quot;: datetime(&quot;2011-01-22T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 4 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Hexviafind&quot;, &quot;start-date&quot;: date(&quot;2010-04-27&quot;), &quot;end-date&quot;: null } ] }
438 { &quot;id&quot;: 3, &quot;alias&quot;: &quot;Emory&quot;, &quot;name&quot;: &quot;EmoryUnk&quot;, &quot;user-since&quot;: datetime(&quot;2012-07-10T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 5, 8, 9 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;geomedia&quot;, &quot;start-date&quot;: date(&quot;2010-06-17&quot;), &quot;end-date&quot;: date(&quot;2010-01-26&quot;) } ] }
439 { &quot;id&quot;: 4, &quot;alias&quot;: &quot;Nicholas&quot;, &quot;name&quot;: &quot;NicholasStroh&quot;, &quot;user-since&quot;: datetime(&quot;2010-12-27T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 2 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Zamcorporation&quot;, &quot;start-date&quot;: date(&quot;2010-06-08&quot;), &quot;end-date&quot;: null } ] }
440</pre></div></div></div>
441<div class="section">
442<h3><a name="Query_1_-_Other_Query_Filters"></a>Query 1 - Other Query Filters</h3>
443<p>AQL can do range queries on any data type that supports the appropriate set of comparators. As an example, this next query retrieves the Facebook users who joined between July 22, 2010 and July 29, 2012:</p>
444
445<div class="source">
446<div class="source">
447<pre> use dataverse TinySocial;
448
449 for $user in dataset FacebookUsers
450 where $user.user-since &gt;= datetime('2010-07-22T00:00:00')
451 and $user.user-since &lt;= datetime('2012-07-29T23:59:59')
452 return $user;
453</pre></div></div>
454<p>The expected result for this query, also an indexable query, is as follows:</p>
455
456<div class="source">
457<div class="source">
458<pre> { &quot;id&quot;: 2, &quot;alias&quot;: &quot;Isbel&quot;, &quot;name&quot;: &quot;IsbelDull&quot;, &quot;user-since&quot;: datetime(&quot;2011-01-22T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 4 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Hexviafind&quot;, &quot;start-date&quot;: date(&quot;2010-04-27&quot;), &quot;end-date&quot;: null } ] }
459 { &quot;id&quot;: 3, &quot;alias&quot;: &quot;Emory&quot;, &quot;name&quot;: &quot;EmoryUnk&quot;, &quot;user-since&quot;: datetime(&quot;2012-07-10T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 5, 8, 9 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;geomedia&quot;, &quot;start-date&quot;: date(&quot;2010-06-17&quot;), &quot;end-date&quot;: date(&quot;2010-01-26&quot;) } ] }
460 { &quot;id&quot;: 4, &quot;alias&quot;: &quot;Nicholas&quot;, &quot;name&quot;: &quot;NicholasStroh&quot;, &quot;user-since&quot;: datetime(&quot;2010-12-27T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 2 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Zamcorporation&quot;, &quot;start-date&quot;: date(&quot;2010-06-08&quot;), &quot;end-date&quot;: null } ] }
461 { &quot;id&quot;: 10, &quot;alias&quot;: &quot;Bram&quot;, &quot;name&quot;: &quot;BramHatch&quot;, &quot;user-since&quot;: datetime(&quot;2010-10-16T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 5, 9 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;physcane&quot;, &quot;start-date&quot;: date(&quot;2007-06-05&quot;), &quot;end-date&quot;: date(&quot;2011-11-05&quot;) } ] }
462</pre></div></div></div>
463<div class="section">
464<h3><a name="Query_2-A_-_Equijoin"></a>Query 2-A - Equijoin</h3>
465<p>In addition to simply binding variables to data instances and returning them &#x201c;whole&#x201d;, an AQL query can construct new ADM instances to return based on combinations of its variable bindings. This gives AQL the power to do joins much like those done using multi-table <i>from</i> clauses in SQL. For example, suppose we wanted a list of all Facebook users paired with their associated messages, with the list enumerating the author name and the message text associated with each Facebook message. We could do this as follows in AQL:</p>
466
467<div class="source">
468<div class="source">
469<pre> use dataverse TinySocial;
470
471 for $user in dataset FacebookUsers
472 for $message in dataset FacebookMessages
473 where $message.author-id = $user.id
474 return {
475 &quot;uname&quot;: $user.name,
476 &quot;message&quot;: $message.message
477 };
478</pre></div></div>
479<p>The result of this query is a sequence of new ADM instances, one for each author/message pair. Each instance in the result will be an ADM record containing two fields, &#x201c;uname&#x201d; and &#x201c;message&#x201d;, containing the user&#x2019;s name and the message text, respectively, for each author/message pair. (Note that &#x201c;uname&#x201d; and &#x201c;message&#x201d; are both simple AQL expressions themselves&#x2014;so in the most general case, even the resulting field names can be computed as part of the query, making AQL a very powerful tool for slicing and dicing semistructured data.)</p>
480<p>The expected result of this example AQL join query for our sample data set is:</p>
481
482<div class="source">
483<div class="source">
484<pre> { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; dislike iphone its touch-screen is horrible&quot; }
485 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; can't stand at&amp;t the network is horrible:(&quot; }
486 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; like verizon the 3G is awesome:)&quot; }
487 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; can't stand motorola the touch-screen is terrible&quot; }
488 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; can't stand at&amp;t its plan is terrible&quot; }
489 { &quot;uname&quot;: &quot;IsbelDull&quot;, &quot;message&quot;: &quot; like samsung the plan is amazing&quot; }
490 { &quot;uname&quot;: &quot;IsbelDull&quot;, &quot;message&quot;: &quot; like t-mobile its platform is mind-blowing&quot; }
491 { &quot;uname&quot;: &quot;EmoryUnk&quot;, &quot;message&quot;: &quot; love sprint its shortcut-menu is awesome:)&quot; }
492 { &quot;uname&quot;: &quot;EmoryUnk&quot;, &quot;message&quot;: &quot; love verizon its wireless is good&quot; }
493 { &quot;uname&quot;: &quot;VonKemble&quot;, &quot;message&quot;: &quot; dislike sprint the speed is horrible&quot; }
494 { &quot;uname&quot;: &quot;WillisWynne&quot;, &quot;message&quot;: &quot; love sprint the customization is mind-blowing&quot; }
495 { &quot;uname&quot;: &quot;SuzannaTillson&quot;, &quot;message&quot;: &quot; like iphone the voicemail-service is awesome&quot; }
496 { &quot;uname&quot;: &quot;WoodrowNehling&quot;, &quot;message&quot;: &quot; love at&amp;t its 3G is good:)&quot; }
497 { &quot;uname&quot;: &quot;BramHatch&quot;, &quot;message&quot;: &quot; can't stand t-mobile its voicemail-service is OMG:(&quot; }
498 { &quot;uname&quot;: &quot;BramHatch&quot;, &quot;message&quot;: &quot; dislike iphone the voice-command is bad:(&quot; }
499</pre></div></div></div>
500<div class="section">
501<h3><a name="Query_2-B_-_Index_join"></a>Query 2-B - Index join</h3>
502<p>By default, AsterixDB evaluates equijoin queries using hash-based join methods that work well for doing ad hoc joins of very large data sets (<a class="externalLink" href="http://en.wikipedia.org/wiki/Hash_join">http://en.wikipedia.org/wiki/Hash_join</a>). On a cluster, hash partitioning is employed as AsterixDB&#x2019;s divide-and-conquer strategy for computing large parallel joins. AsterixDB includes other join methods, but in the absence of data statistics and selectivity estimates, it doesn&#x2019;t (yet) have the know-how to intelligently choose among its alternatives. We therefore asked ourselves the classic question&#x2014;WWOD?&#x2014;What Would Oracle Do?&#x2014;and in the interim, AQL includes a clunky (but useful) hint-based mechanism for addressing the occasional need to suggest to AsterixDB which join method it should use for a particular AQL query.</p>
503<p>The following query is similar to Query 2-A but includes a suggestion to AsterixDB that it should consider employing an index-based nested-loop join technique to process the query:</p>
504
505<div class="source">
506<div class="source">
507<pre> use dataverse TinySocial;
508
509 for $user in dataset FacebookUsers
510 for $message in dataset FacebookMessages
511 where $message.author-id /*+ indexnl */ = $user.id
512 return {
513 &quot;uname&quot;: $user.name,
514 &quot;message&quot;: $message.message
515 };
516</pre></div></div>
517<p>The expected result is (of course) the same as before, modulo the order of the instances. Result ordering is (intentionally) undefined in AQL in the absence of an <i>order by</i> clause. The query result for our sample data in this case is:</p>
518
519<div class="source">
520<div class="source">
521<pre> { &quot;uname&quot;: &quot;EmoryUnk&quot;, &quot;message&quot;: &quot; love sprint its shortcut-menu is awesome:)&quot; }
522 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; dislike iphone its touch-screen is horrible&quot; }
523 { &quot;uname&quot;: &quot;IsbelDull&quot;, &quot;message&quot;: &quot; like samsung the plan is amazing&quot; }
524 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; can't stand at&amp;t the network is horrible:(&quot; }
525 { &quot;uname&quot;: &quot;WillisWynne&quot;, &quot;message&quot;: &quot; love sprint the customization is mind-blowing&quot; }
526 { &quot;uname&quot;: &quot;IsbelDull&quot;, &quot;message&quot;: &quot; like t-mobile its platform is mind-blowing&quot; }
527 { &quot;uname&quot;: &quot;VonKemble&quot;, &quot;message&quot;: &quot; dislike sprint the speed is horrible&quot; }
528 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; like verizon the 3G is awesome:)&quot; }
529 { &quot;uname&quot;: &quot;EmoryUnk&quot;, &quot;message&quot;: &quot; love verizon its wireless is good&quot; }
530 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; can't stand motorola the touch-screen is terrible&quot; }
531 { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;message&quot;: &quot; can't stand at&amp;t its plan is terrible&quot; }
532 { &quot;uname&quot;: &quot;BramHatch&quot;, &quot;message&quot;: &quot; can't stand t-mobile its voicemail-service is OMG:(&quot; }
533 { &quot;uname&quot;: &quot;BramHatch&quot;, &quot;message&quot;: &quot; dislike iphone the voice-command is bad:(&quot; }
534 { &quot;uname&quot;: &quot;WoodrowNehling&quot;, &quot;message&quot;: &quot; love at&amp;t its 3G is good:)&quot; }
535 { &quot;uname&quot;: &quot;SuzannaTillson&quot;, &quot;message&quot;: &quot; like iphone the voicemail-service is awesome&quot; }
536</pre></div></div>
537<p>(It is worth knowing, with respect to influencing AsterixDB&#x2019;s query evaluation, that nested <i>for</i> clauses&#x2014;a.k.a. joins&#x2014; are currently evaluated with the &#x201c;outer&#x201d; clause probing the data of the &#x201c;inner&#x201d; clause.)</p></div>
538<div class="section">
539<h3><a name="Query_3_-_Nested_Outer_Join"></a>Query 3 - Nested Outer Join</h3>
540<p>In order to support joins between tables with missing/dangling join tuples, the designers of SQL ended up shoe-horning a subset of the relational algebra into SQL&#x2019;s <i>from</i> clause syntax&#x2014;and providing a variety of join types there for users to choose from. Left outer joins are particularly important in SQL, e.g., to print a summary of customers and orders, grouped by customer, without omitting those customers who haven&#x2019;t placed any orders yet.</p>
541<p>The AQL language supports nesting, both of queries and of query results, and the combination allows for an arguably cleaner/more natural approach to such queries. As an example, supposed we wanted, for each Facebook user, to produce a record that has his/her name plus a list of the messages written by that user. In SQL, this would involve a left outer join between users and messages, grouping by user, and having the user name repeated along side each message. In AQL, this sort of use case can be handled (more naturally) as follows:</p>
542
543<div class="source">
544<div class="source">
545<pre> use dataverse TinySocial;
546
547 for $user in dataset FacebookUsers
548 return {
549 &quot;uname&quot;: $user.name,
550 &quot;messages&quot;: for $message in dataset FacebookMessages
551 where $message.author-id = $user.id
552 return $message.message
553 };
554</pre></div></div>
555<p>This AQL query binds the variable <tt>$user</tt> to the data instances in FacebookUsers; for each user, it constructs a result record containing a &#x201c;uname&#x201d; field with the user&#x2019;s name and a &#x201c;messages&#x201d; field with a nested collection of all messages for that user. The nested collection for each user is specified by using a correlated subquery. (Note: While it looks like nested loops could be involved in computing the result, AsterixDB recogizes the equivalence of such a query to an outerjoin, and it will use an efficient hash-based strategy when actually computing the query&#x2019;s result.)</p>
556<p>Here is this example query&#x2019;s expected output:</p>
557
558<div class="source">
559<div class="source">
560<pre> { &quot;uname&quot;: &quot;MargaritaStoddard&quot;, &quot;messages&quot;: [ &quot; dislike iphone its touch-screen is horrible&quot;, &quot; can't stand at&amp;t the network is horrible:(&quot;, &quot; like verizon the 3G is awesome:)&quot;, &quot; can't stand motorola the touch-screen is terrible&quot;, &quot; can't stand at&amp;t its plan is terrible&quot; ] }
561 { &quot;uname&quot;: &quot;IsbelDull&quot;, &quot;messages&quot;: [ &quot; like samsung the plan is amazing&quot;, &quot; like t-mobile its platform is mind-blowing&quot; ] }
562 { &quot;uname&quot;: &quot;EmoryUnk&quot;, &quot;messages&quot;: [ &quot; love sprint its shortcut-menu is awesome:)&quot;, &quot; love verizon its wireless is good&quot; ] }
563 { &quot;uname&quot;: &quot;NicholasStroh&quot;, &quot;messages&quot;: [ ] }
564 { &quot;uname&quot;: &quot;VonKemble&quot;, &quot;messages&quot;: [ &quot; dislike sprint the speed is horrible&quot; ] }
565 { &quot;uname&quot;: &quot;WillisWynne&quot;, &quot;messages&quot;: [ &quot; love sprint the customization is mind-blowing&quot; ] }
566 { &quot;uname&quot;: &quot;SuzannaTillson&quot;, &quot;messages&quot;: [ &quot; like iphone the voicemail-service is awesome&quot; ] }
567 { &quot;uname&quot;: &quot;NilaMilliron&quot;, &quot;messages&quot;: [ ] }
568 { &quot;uname&quot;: &quot;WoodrowNehling&quot;, &quot;messages&quot;: [ &quot; love at&amp;t its 3G is good:)&quot; ] }
569 { &quot;uname&quot;: &quot;BramHatch&quot;, &quot;messages&quot;: [ &quot; dislike iphone the voice-command is bad:(&quot;, &quot; can't stand t-mobile its voicemail-service is OMG:(&quot; ] }
570</pre></div></div></div>
571<div class="section">
572<h3><a name="Query_4_-_Theta_Join"></a>Query 4 - Theta Join</h3>
573<p>Not all joins are expressible as equijoins and computable using equijoin-oriented algorithms. The join predicates for some use cases involve predicates with functions; AsterixDB supports the expression of such queries and will still evaluate them as best it can using nested loop based techniques (and broadcast joins in the parallel case).</p>
574<p>As an example of such a use case, suppose that we wanted, for each tweet T, to find all of the other tweets that originated from within a circle of radius of 1 surrounding tweet T&#x2019;s location. In AQL, this can be specified in a manner similar to the previous query using one of the built-in functions on the spatial data type instead of id equality in the correlated query&#x2019;s <i>where</i> clause:</p>
575
576<div class="source">
577<div class="source">
578<pre> use dataverse TinySocial;
579
580 for $t in dataset TweetMessages
581 return {
582 &quot;message&quot;: $t.message-text,
583 &quot;nearby-messages&quot;: for $t2 in dataset TweetMessages
584 where spatial-distance($t.sender-location, $t2.sender-location) &lt;= 1
585 return { &quot;msgtxt&quot;:$t2.message-text}
586 };
587</pre></div></div>
588<p>Here is the expected result for this query:</p>
589
590<div class="source">
591<div class="source">
592<pre> { &quot;message&quot;: &quot; love t-mobile its customization is good:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; love t-mobile its customization is good:)&quot; } ] }
593 { &quot;message&quot;: &quot; hate verizon its voice-clarity is OMG:(&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like motorola the speed is good:)&quot; }, { &quot;msgtxt&quot;: &quot; hate verizon its voice-clarity is OMG:(&quot; } ] }
594 { &quot;message&quot;: &quot; can't stand iphone its platform is terrible&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; can't stand iphone its platform is terrible&quot; } ] }
595 { &quot;message&quot;: &quot; like samsung the voice-command is amazing:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like samsung the voice-command is amazing:)&quot; } ] }
596 { &quot;message&quot;: &quot; like verizon its shortcut-menu is awesome:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like verizon its shortcut-menu is awesome:)&quot; } ] }
597 { &quot;message&quot;: &quot; like motorola the speed is good:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; hate verizon its voice-clarity is OMG:(&quot; }, { &quot;msgtxt&quot;: &quot; like motorola the speed is good:)&quot; } ] }
598 { &quot;message&quot;: &quot; like sprint the voice-command is mind-blowing:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like sprint the voice-command is mind-blowing:)&quot; } ] }
599 { &quot;message&quot;: &quot; can't stand motorola its speed is terrible:(&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; can't stand motorola its speed is terrible:(&quot; } ] }
600 { &quot;message&quot;: &quot; like iphone the voice-clarity is good:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like iphone the voice-clarity is good:)&quot; } ] }
601 { &quot;message&quot;: &quot; like samsung the platform is good&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like samsung the platform is good&quot; } ] }
602 { &quot;message&quot;: &quot; like t-mobile the shortcut-menu is awesome:)&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; like t-mobile the shortcut-menu is awesome:)&quot; } ] }
603 { &quot;message&quot;: &quot; love verizon its voicemail-service is awesome&quot;, &quot;nearby-messages&quot;: [ { &quot;msgtxt&quot;: &quot; love verizon its voicemail-service is awesome&quot; } ] }
604</pre></div></div></div>
605<div class="section">
606<h3><a name="Query_5_-_Fuzzy_Join"></a>Query 5 - Fuzzy Join</h3>
607<p>As another example of a non-equijoin use case, we could ask AsterixDB to find, for each Facebook user, all Twitter users with names &#x201c;similar&#x201d; to their name. AsterixDB supports a variety of &#x201c;fuzzy match&#x201d; functions for use with textual and set-based data. As one example, we could choose to use edit distance with a threshold of 3 as the definition of name similarity, in which case we could write the following query using AQL&#x2019;s operator-based syntax (~=) for testing whether or not two values are similar:</p>
608
609<div class="source">
610<div class="source">
611<pre> use dataverse TinySocial;
612
613 set simfunction &quot;edit-distance&quot;;
614 set simthreshold &quot;3&quot;;
615
616 for $fbu in dataset FacebookUsers
617 return {
618 &quot;id&quot;: $fbu.id,
619 &quot;name&quot;: $fbu.name,
620 &quot;similar-users&quot;: for $t in dataset TweetMessages
621 let $tu := $t.user
622 where $tu.name ~= $fbu.name
623 return {
624 &quot;twitter-screenname&quot;: $tu.screen-name,
625 &quot;twitter-name&quot;: $tu.name
626 }
627 };
628</pre></div></div>
629<p>The expected result for this query against our sample data is:</p>
630
631<div class="source">
632<div class="source">
633<pre> { &quot;id&quot;: 1, &quot;name&quot;: &quot;MargaritaStoddard&quot;, &quot;similar-users&quot;: [ ] }
634 { &quot;id&quot;: 2, &quot;name&quot;: &quot;IsbelDull&quot;, &quot;similar-users&quot;: [ ] }
635 { &quot;id&quot;: 3, &quot;name&quot;: &quot;EmoryUnk&quot;, &quot;similar-users&quot;: [ ] }
636 { &quot;id&quot;: 4, &quot;name&quot;: &quot;NicholasStroh&quot;, &quot;similar-users&quot;: [ ] }
637 { &quot;id&quot;: 5, &quot;name&quot;: &quot;VonKemble&quot;, &quot;similar-users&quot;: [ ] }
638 { &quot;id&quot;: 6, &quot;name&quot;: &quot;WillisWynne&quot;, &quot;similar-users&quot;: [ ] }
639 { &quot;id&quot;: 7, &quot;name&quot;: &quot;SuzannaTillson&quot;, &quot;similar-users&quot;: [ ] }
640 { &quot;id&quot;: 8, &quot;name&quot;: &quot;NilaMilliron&quot;, &quot;similar-users&quot;: [ { &quot;twitter-screenname&quot;: &quot;NilaMilliron_tw&quot;, &quot;twitter-name&quot;: &quot;Nila Milliron&quot; } ] }
641 { &quot;id&quot;: 9, &quot;name&quot;: &quot;WoodrowNehling&quot;, &quot;similar-users&quot;: [ ] }
642 { &quot;id&quot;: 10, &quot;name&quot;: &quot;BramHatch&quot;, &quot;similar-users&quot;: [ ] }
643</pre></div></div></div>
644<div class="section">
645<h3><a name="Query_6_-_Existential_Quantification"></a>Query 6 - Existential Quantification</h3>
646<p>The expressive power of AQL includes support for queries involving &#x201c;some&#x201d; (existentially quantified) and &#x201c;all&#x201d; (universally quantified) query semantics. As an example of an existential AQL query, here we show a query to list the Facebook users who are currently employed. Such employees will have an employment history containing a record with a null end-date value, which leads us to the following AQL query:</p>
647
648<div class="source">
649<div class="source">
650<pre> use dataverse TinySocial;
651
652 for $fbu in dataset FacebookUsers
653 where (some $e in $fbu.employment satisfies is-null($e.end-date))
654 return $fbu;
655</pre></div></div>
656<p>The expected result in this case is:</p>
657
658<div class="source">
659<div class="source">
660<pre> { &quot;id&quot;: 1, &quot;alias&quot;: &quot;Margarita&quot;, &quot;name&quot;: &quot;MargaritaStoddard&quot;, &quot;user-since&quot;: datetime(&quot;2012-08-20T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 2, 3, 6, 10 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Codetechno&quot;, &quot;start-date&quot;: date(&quot;2006-08-06&quot;), &quot;end-date&quot;: null } ] }
661 { &quot;id&quot;: 2, &quot;alias&quot;: &quot;Isbel&quot;, &quot;name&quot;: &quot;IsbelDull&quot;, &quot;user-since&quot;: datetime(&quot;2011-01-22T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 4 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Hexviafind&quot;, &quot;start-date&quot;: date(&quot;2010-04-27&quot;), &quot;end-date&quot;: null } ] }
662 { &quot;id&quot;: 4, &quot;alias&quot;: &quot;Nicholas&quot;, &quot;name&quot;: &quot;NicholasStroh&quot;, &quot;user-since&quot;: datetime(&quot;2010-12-27T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 2 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Zamcorporation&quot;, &quot;start-date&quot;: date(&quot;2010-06-08&quot;), &quot;end-date&quot;: null } ] }
663 { &quot;id&quot;: 5, &quot;alias&quot;: &quot;Von&quot;, &quot;name&quot;: &quot;VonKemble&quot;, &quot;user-since&quot;: datetime(&quot;2010-01-05T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 3, 6, 10 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Kongreen&quot;, &quot;start-date&quot;: date(&quot;2010-11-27&quot;), &quot;end-date&quot;: null } ] }
664 { &quot;id&quot;: 6, &quot;alias&quot;: &quot;Willis&quot;, &quot;name&quot;: &quot;WillisWynne&quot;, &quot;user-since&quot;: datetime(&quot;2005-01-17T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 3, 7 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;jaydax&quot;, &quot;start-date&quot;: date(&quot;2009-05-15&quot;), &quot;end-date&quot;: null } ] }
665 { &quot;id&quot;: 7, &quot;alias&quot;: &quot;Suzanna&quot;, &quot;name&quot;: &quot;SuzannaTillson&quot;, &quot;user-since&quot;: datetime(&quot;2012-08-07T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 6 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Labzatron&quot;, &quot;start-date&quot;: date(&quot;2011-04-19&quot;), &quot;end-date&quot;: null } ] }
666 { &quot;id&quot;: 8, &quot;alias&quot;: &quot;Nila&quot;, &quot;name&quot;: &quot;NilaMilliron&quot;, &quot;user-since&quot;: datetime(&quot;2008-01-01T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 3 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Plexlane&quot;, &quot;start-date&quot;: date(&quot;2010-02-28&quot;), &quot;end-date&quot;: null } ] }
667</pre></div></div></div>
668<div class="section">
669<h3><a name="Query_7_-_Universal_Quantification"></a>Query 7 - Universal Quantification</h3>
670<p>As an example of a universal AQL query, here we show a query to list the Facebook users who are currently unemployed. Such employees will have an employment history containing no records with null end-date values, leading us to the following AQL query:</p>
671
672<div class="source">
673<div class="source">
674<pre> use dataverse TinySocial;
675
676 for $fbu in dataset FacebookUsers
677 where (every $e in $fbu.employment satisfies not(is-null($e.end-date)))
678 return $fbu;
679</pre></div></div>
680<p>Here is the expected result for our sample data:</p>
681
682<div class="source">
683<div class="source">
684<pre> { &quot;id&quot;: 3, &quot;alias&quot;: &quot;Emory&quot;, &quot;name&quot;: &quot;EmoryUnk&quot;, &quot;user-since&quot;: datetime(&quot;2012-07-10T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 5, 8, 9 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;geomedia&quot;, &quot;start-date&quot;: date(&quot;2010-06-17&quot;), &quot;end-date&quot;: date(&quot;2010-01-26&quot;) } ] }
685 { &quot;id&quot;: 9, &quot;alias&quot;: &quot;Woodrow&quot;, &quot;name&quot;: &quot;WoodrowNehling&quot;, &quot;user-since&quot;: datetime(&quot;2005-09-20T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 3, 10 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;Zuncan&quot;, &quot;start-date&quot;: date(&quot;2003-04-22&quot;), &quot;end-date&quot;: date(&quot;2009-12-13&quot;) } ] }
686 { &quot;id&quot;: 10, &quot;alias&quot;: &quot;Bram&quot;, &quot;name&quot;: &quot;BramHatch&quot;, &quot;user-since&quot;: datetime(&quot;2010-10-16T10:10:00.000Z&quot;), &quot;friend-ids&quot;: {{ 1, 5, 9 }}, &quot;employment&quot;: [ { &quot;organization-name&quot;: &quot;physcane&quot;, &quot;start-date&quot;: date(&quot;2007-06-05&quot;), &quot;end-date&quot;: date(&quot;2011-11-05&quot;) } ] }
687</pre></div></div></div>
688<div class="section">
689<h3><a name="Query_8_-_Simple_Aggregation"></a>Query 8 - Simple Aggregation</h3>
690<p>Like SQL, the AQL language of AsterixDB provides support for computing aggregates over large amounts of data. As a very simple example, the following AQL query computes the total number of Facebook users:</p>
691
692<div class="source">
693<div class="source">
694<pre> use dataverse TinySocial;
695
696 count(for $fbu in dataset FacebookUsers return $fbu);
697</pre></div></div>
698<p>In AQL, aggregate functions can be applied to arbitrary subquery results; in this case, the count function is applied to the result of a query that enumerates the Facebook users. The expected result here is:</p>
699
700<div class="source">
701<div class="source">
702<pre> 10
703</pre></div></div></div>
704<div class="section">
705<h3><a name="Query_9-A_-_Grouping_and_Aggregation"></a>Query 9-A - Grouping and Aggregation</h3>
706<p>Also like SQL, AQL supports grouped aggregation. For every Twitter user, the following group-by/aggregate query counts the number of tweets sent by that user:</p>
707
708<div class="source">
709<div class="source">
710<pre> use dataverse TinySocial;
711
712 for $t in dataset TweetMessages
713 group by $uid := $t.user.screen-name with $t
714 return {
715 &quot;user&quot;: $uid,
716 &quot;count&quot;: count($t)
717 };
718</pre></div></div>
719<p>The <i>for</i> clause incrementally binds $t to tweets, and the <i>group by</i> clause groups the tweets by its issuer&#x2019;s Twitter screen-name. Unlike SQL, where data is tabular&#x2014;flat&#x2014;the data model underlying AQL allows for nesting. Thus, following the <i>group by</i> clause, the <i>return</i> clause in this query sees a sequence of $t groups, with each such group having an associated $uid variable value (i.e., the tweeting user&#x2019;s screen name). In the context of the return clause, due to &#x201c;&#x2026; with $t &#x2026;&#x201d;, $uid is bound to the tweeter&#x2019;s id and $t is bound to the <i>set</i> of tweets issued by that tweeter. The return clause constructs a result record containing the tweeter&#x2019;s user id and the count of the items in the associated tweet set. The query result will contain one such record per screen name. This query also illustrates another feature of AQL; notice that each user&#x2019;s screen name is accessed via a path syntax that traverses each tweet&#x2019;s nested record structure.</p>
720<p>Here is the expected result for this query over the sample data:</p>
721
722<div class="source">
723<div class="source">
724<pre> { &quot;user&quot;: &quot;ChangEwing_573&quot;, &quot;count&quot;: 1 }
725 { &quot;user&quot;: &quot;ColineGeyer@63&quot;, &quot;count&quot;: 3 }
726 { &quot;user&quot;: &quot;NathanGiesen@211&quot;, &quot;count&quot;: 6 }
727 { &quot;user&quot;: &quot;NilaMilliron_tw&quot;, &quot;count&quot;: 1 }
728 { &quot;user&quot;: &quot;OliJackson_512&quot;, &quot;count&quot;: 1 }
729</pre></div></div></div>
730<div class="section">
731<h3><a name="Query_9-B_-_Hash-Based_Grouping_and_Aggregation"></a>Query 9-B - (Hash-Based) Grouping and Aggregation</h3>
732<p>As for joins, AsterixDB has multiple evaluation strategies available for processing grouped aggregate queries. For grouped aggregation, the system knows how to employ both sort-based and hash-based aggregation methods, with sort-based methods being used by default and a hint being available to suggest that a different approach be used in processing a particular AQL query.</p>
733<p>The following query is similar to Query 9-A, but adds a hash-based aggregation hint:</p>
734
735<div class="source">
736<div class="source">
737<pre> use dataverse TinySocial;
738
739 for $t in dataset TweetMessages
740 /*+ hash*/
741 group by $uid := $t.user.screen-name with $t
742 return {
743 &quot;user&quot;: $uid,
744 &quot;count&quot;: count($t)
745 };
746</pre></div></div>
747<p>Here is the expected result:</p>
748
749<div class="source">
750<div class="source">
751<pre> { &quot;user&quot;: &quot;OliJackson_512&quot;, &quot;count&quot;: 1 }
752 { &quot;user&quot;: &quot;ColineGeyer@63&quot;, &quot;count&quot;: 3 }
753 { &quot;user&quot;: &quot;NathanGiesen@211&quot;, &quot;count&quot;: 6 }
754 { &quot;user&quot;: &quot;NilaMilliron_tw&quot;, &quot;count&quot;: 1 }
755 { &quot;user&quot;: &quot;ChangEwing_573&quot;, &quot;count&quot;: 1 }
756</pre></div></div></div>
757<div class="section">
758<h3><a name="Query_10_-_Grouping_and_Limits"></a>Query 10 - Grouping and Limits</h3>
759<p>In some use cases it is not necessary to compute the entire answer to a query. In some cases, just having the first <i>N</i> or top <i>N</i> results is sufficient. This is expressible in AQL using the <i>limit</i> clause combined with the <i>order by</i> clause.</p>
760<p>The following AQL query returns the top 3 Twitter users based on who has issued the most tweets:</p>
761
762<div class="source">
763<div class="source">
764<pre> use dataverse TinySocial;
765
766 for $t in dataset TweetMessages
767 group by $uid := $t.user.screen-name with $t
768 let $c := count($t)
769 order by $c desc
770 limit 3
771 return {
772 &quot;user&quot;: $uid,
773 &quot;count&quot;: $c
774 };
775</pre></div></div>
776<p>The expected result for this query is:</p>
777
778<div class="source">
779<div class="source">
780<pre> { &quot;user&quot;: &quot;NathanGiesen@211&quot;, &quot;count&quot;: 6 }
781 { &quot;user&quot;: &quot;ColineGeyer@63&quot;, &quot;count&quot;: 3 }
782 { &quot;user&quot;: &quot;NilaMilliron_tw&quot;, &quot;count&quot;: 1 }
783</pre></div></div></div>
784<div class="section">
785<h3><a name="Query_11_-_Left_Outer_Fuzzy_Join"></a>Query 11 - Left Outer Fuzzy Join</h3>
786<p>As a last example of AQL and its query power, the following query, for each tweet, finds all of the tweets that are similar based on the topics that they refer to:</p>
787
788<div class="source">
789<div class="source">
790<pre> use dataverse TinySocial;
791
792 set simfunction &quot;jaccard&quot;;
793 set simthreshold &quot;0.3&quot;;
794
795 for $t in dataset TweetMessages
796 return {
797 &quot;tweet&quot;: $t,
798 &quot;similar-tweets&quot;: for $t2 in dataset TweetMessages
799 where $t2.referred-topics ~= $t.referred-topics
800 and $t2.tweetid != $t.tweetid
801 return $t2.referred-topics
802 };
803</pre></div></div>
804<p>This query illustrates several things worth knowing in order to write fuzzy queries in AQL. First, as mentioned earlier, AQL offers an operator-based syntax for seeing whether two values are &#x201c;similar&#x201d; to one another or not. Second, recall that the referred-topics field of records of datatype TweetMessageType is a bag of strings. This query sets the context for its similarity join by requesting that Jaccard-based similarity semantics (<a class="externalLink" href="http://en.wikipedia.org/wiki/Jaccard_index">http://en.wikipedia.org/wiki/Jaccard_index</a>) be used for the query&#x2019;s similarity operator and that a similarity index of 0.3 be used as its similarity threshold.</p>
805<p>The expected result for this fuzzy join query is:</p>
806
807<div class="source">
808<div class="source">
809<pre> { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;1&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NathanGiesen@211&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 39339, &quot;statuses_count&quot;: 473, &quot;name&quot;: &quot;Nathan Giesen&quot;, &quot;followers_count&quot;: 49416 }, &quot;sender-location&quot;: point(&quot;47.44,80.65&quot;), &quot;send-time&quot;: datetime(&quot;2008-04-26T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;t-mobile&quot;, &quot;customization&quot; }}, &quot;message-text&quot;: &quot; love t-mobile its customization is good:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;t-mobile&quot;, &quot;shortcut-menu&quot; }} ] }
810 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;10&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;ColineGeyer@63&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 121, &quot;statuses_count&quot;: 362, &quot;name&quot;: &quot;Coline Geyer&quot;, &quot;followers_count&quot;: 17159 }, &quot;sender-location&quot;: point(&quot;29.15,76.53&quot;), &quot;send-time&quot;: datetime(&quot;2008-01-26T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;verizon&quot;, &quot;voice-clarity&quot; }}, &quot;message-text&quot;: &quot; hate verizon its voice-clarity is OMG:(&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;iphone&quot;, &quot;voice-clarity&quot; }}, {{ &quot;verizon&quot;, &quot;voicemail-service&quot; }}, {{ &quot;verizon&quot;, &quot;shortcut-menu&quot; }} ] }
811 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;11&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NilaMilliron_tw&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 445, &quot;statuses_count&quot;: 164, &quot;name&quot;: &quot;Nila Milliron&quot;, &quot;followers_count&quot;: 22649 }, &quot;sender-location&quot;: point(&quot;37.59,68.42&quot;), &quot;send-time&quot;: datetime(&quot;2008-03-09T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;iphone&quot;, &quot;platform&quot; }}, &quot;message-text&quot;: &quot; can't stand iphone its platform is terrible&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;iphone&quot;, &quot;voice-clarity&quot; }}, {{ &quot;samsung&quot;, &quot;platform&quot; }} ] }
812 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;12&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;OliJackson_512&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 445, &quot;statuses_count&quot;: 164, &quot;name&quot;: &quot;Oli Jackson&quot;, &quot;followers_count&quot;: 22649 }, &quot;sender-location&quot;: point(&quot;24.82,94.63&quot;), &quot;send-time&quot;: datetime(&quot;2010-02-13T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;samsung&quot;, &quot;voice-command&quot; }}, &quot;message-text&quot;: &quot; like samsung the voice-command is amazing:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;samsung&quot;, &quot;platform&quot; }}, {{ &quot;sprint&quot;, &quot;voice-command&quot; }} ] }
813 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;2&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;ColineGeyer@63&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 121, &quot;statuses_count&quot;: 362, &quot;name&quot;: &quot;Coline Geyer&quot;, &quot;followers_count&quot;: 17159 }, &quot;sender-location&quot;: point(&quot;32.84,67.14&quot;), &quot;send-time&quot;: datetime(&quot;2010-05-13T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;verizon&quot;, &quot;shortcut-menu&quot; }}, &quot;message-text&quot;: &quot; like verizon its shortcut-menu is awesome:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;verizon&quot;, &quot;voicemail-service&quot; }}, {{ &quot;verizon&quot;, &quot;voice-clarity&quot; }}, {{ &quot;t-mobile&quot;, &quot;shortcut-menu&quot; }} ] }
814 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;3&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NathanGiesen@211&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 39339, &quot;statuses_count&quot;: 473, &quot;name&quot;: &quot;Nathan Giesen&quot;, &quot;followers_count&quot;: 49416 }, &quot;sender-location&quot;: point(&quot;29.72,75.8&quot;), &quot;send-time&quot;: datetime(&quot;2006-11-04T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;motorola&quot;, &quot;speed&quot; }}, &quot;message-text&quot;: &quot; like motorola the speed is good:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;motorola&quot;, &quot;speed&quot; }} ] }
815 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;4&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NathanGiesen@211&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 39339, &quot;statuses_count&quot;: 473, &quot;name&quot;: &quot;Nathan Giesen&quot;, &quot;followers_count&quot;: 49416 }, &quot;sender-location&quot;: point(&quot;39.28,70.48&quot;), &quot;send-time&quot;: datetime(&quot;2011-12-26T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;sprint&quot;, &quot;voice-command&quot; }}, &quot;message-text&quot;: &quot; like sprint the voice-command is mind-blowing:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;samsung&quot;, &quot;voice-command&quot; }} ] }
816 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;5&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NathanGiesen@211&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 39339, &quot;statuses_count&quot;: 473, &quot;name&quot;: &quot;Nathan Giesen&quot;, &quot;followers_count&quot;: 49416 }, &quot;sender-location&quot;: point(&quot;40.09,92.69&quot;), &quot;send-time&quot;: datetime(&quot;2006-08-04T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;motorola&quot;, &quot;speed&quot; }}, &quot;message-text&quot;: &quot; can't stand motorola its speed is terrible:(&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;motorola&quot;, &quot;speed&quot; }} ] }
817 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;6&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;ColineGeyer@63&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 121, &quot;statuses_count&quot;: 362, &quot;name&quot;: &quot;Coline Geyer&quot;, &quot;followers_count&quot;: 17159 }, &quot;sender-location&quot;: point(&quot;47.51,83.99&quot;), &quot;send-time&quot;: datetime(&quot;2010-05-07T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;iphone&quot;, &quot;voice-clarity&quot; }}, &quot;message-text&quot;: &quot; like iphone the voice-clarity is good:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;verizon&quot;, &quot;voice-clarity&quot; }}, {{ &quot;iphone&quot;, &quot;platform&quot; }} ] }
818 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;7&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;ChangEwing_573&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 182, &quot;statuses_count&quot;: 394, &quot;name&quot;: &quot;Chang Ewing&quot;, &quot;followers_count&quot;: 32136 }, &quot;sender-location&quot;: point(&quot;36.21,72.6&quot;), &quot;send-time&quot;: datetime(&quot;2011-08-25T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;samsung&quot;, &quot;platform&quot; }}, &quot;message-text&quot;: &quot; like samsung the platform is good&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;iphone&quot;, &quot;platform&quot; }}, {{ &quot;samsung&quot;, &quot;voice-command&quot; }} ] }
819 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;8&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NathanGiesen@211&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 39339, &quot;statuses_count&quot;: 473, &quot;name&quot;: &quot;Nathan Giesen&quot;, &quot;followers_count&quot;: 49416 }, &quot;sender-location&quot;: point(&quot;46.05,93.34&quot;), &quot;send-time&quot;: datetime(&quot;2005-10-14T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;t-mobile&quot;, &quot;shortcut-menu&quot; }}, &quot;message-text&quot;: &quot; like t-mobile the shortcut-menu is awesome:)&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;t-mobile&quot;, &quot;customization&quot; }}, {{ &quot;verizon&quot;, &quot;shortcut-menu&quot; }} ] }
820 { &quot;tweet&quot;: { &quot;tweetid&quot;: &quot;9&quot;, &quot;user&quot;: { &quot;screen-name&quot;: &quot;NathanGiesen@211&quot;, &quot;lang&quot;: &quot;en&quot;, &quot;friends_count&quot;: 39339, &quot;statuses_count&quot;: 473, &quot;name&quot;: &quot;Nathan Giesen&quot;, &quot;followers_count&quot;: 49416 }, &quot;sender-location&quot;: point(&quot;36.86,74.62&quot;), &quot;send-time&quot;: datetime(&quot;2012-07-21T10:10:00.000Z&quot;), &quot;referred-topics&quot;: {{ &quot;verizon&quot;, &quot;voicemail-service&quot; }}, &quot;message-text&quot;: &quot; love verizon its voicemail-service is awesome&quot; }, &quot;similar-tweets&quot;: [ {{ &quot;verizon&quot;, &quot;voice-clarity&quot; }}, {{ &quot;verizon&quot;, &quot;shortcut-menu&quot; }} ] }
821</pre></div></div></div>
822<div class="section">
823<h3><a name="Inserting_New_Data"></a>Inserting New Data</h3>
824<p>In addition to loading and querying data, AsterixDB supports incremental additions to datasets via the AQL <i>insert</i> statement.</p>
825<p>The following example adds a new tweet by user &#x201c;<a class="externalLink" href="mailto:NathanGiesen@211">NathanGiesen@211</a>&#x201d; to the TweetMessages dataset. (An astute reader may notice that this tweet was issued a half an hour after his last tweet, so his counts have all gone up in the interim, although he appears not to have moved in the last half hour.)</p>
826
827<div class="source">
828<div class="source">
829<pre> use dataverse TinySocial;
830
831 insert into dataset TweetMessages
832 (
833 {&quot;tweetid&quot;:&quot;13&quot;,
834 &quot;user&quot;:
835 {&quot;screen-name&quot;:&quot;NathanGiesen@211&quot;,
836 &quot;lang&quot;:&quot;en&quot;,
837 &quot;friends_count&quot;:39345,
838 &quot;statuses_count&quot;:479,
839 &quot;name&quot;:&quot;Nathan Giesen&quot;,
840 &quot;followers_count&quot;:49420
841 },
842 &quot;sender-location&quot;:point(&quot;47.44,80.65&quot;),
843 &quot;send-time&quot;:datetime(&quot;2008-04-26T10:10:35&quot;),
844 &quot;referred-topics&quot;:{{&quot;tweeting&quot;}},
845 &quot;message-text&quot;:&quot;tweety tweet, my fellow tweeters!&quot;
846 }
847 );
848</pre></div></div>
849<p>In general, the data to be inserted may be specified using any valid AQL query expression. The insertion of a single object instance, as in this example, is just a special case where the query expression happens to be a record constructor involving only constants.</p></div>
850<div class="section">
851<h3><a name="Deleting_Existing_Data"></a>Deleting Existing Data</h3>
852<p>In addition to inserting new data, AsterixDB supports deletion from datasets via the AQL <i>delete</i> statement. The statement supports &#x201c;searched delete&#x201d; semantics, and its <i>where</i> clause can involve any valid XQuery expression.</p>
853<p>The following example deletes the tweet that we just added from user &quot;<a class="externalLink" href="mailto:NathanGiesen@211&quot;">NathanGiesen@211&quot;</a>. (Easy come, easy go. :-))</p>
854
855<div class="source">
856<div class="source">
857<pre> use dataverse TinySocial;
858
859 delete $tm from dataset TweetMessages where $tm.tweetid = &quot;13&quot;;
860</pre></div></div>
861<p>It should be noted that one form of data change not yet supported by AsterixDB is in-place data modification (<i>update</i>). Currently, only insert and delete operations are supported; update is not. To achieve the effect of an update, two statements are currently needed&#x2014;one to delete the old record from the dataset where it resides, and another to insert the new replacement record (with the same primary key but with different field values for some of the associated data content).</p></div>
862<div class="section">
863<h3><a name="Transaction_Support"></a>Transaction Support</h3>
864<p>AsterixDB supports record-level ACID transactions that begin and terminate implicitly for each record inserted, deleted, or searched while a given AQL statement is being executed. This is quite similar to the level of transaction support found in today&#x2019;s NoSQL stores. AsterixDB does not support multi-statement transactions, and in fact an AQL statement that involves multiple records can itself involve multiple independent record-level transactions. An example consequence of this is that, when an AQL statement attempts to insert 1000 records, it is possible that the first 800 records could end up being committed while the remaining 200 records fail to be inserted. This situation could happen, for example, if a duplicate key exception occurs as the 801st insertion is attempted. If this happens, AsterixDB will report the error (e.g., a duplicate key exception) as the result of the offending AQL insert statement, and the application logic above will need to take the appropriate action(s) needed to assess the resulting state and to clean up and/or continue as appropriate.</p></div></div>
865<div class="section">
866<h2><a name="Further_Help"></a>Further Help</h2>
867<p>That&#x2019;s it You are now armed and dangerous with respect to semistructured data management using AsterixDB.</p>
868<p>AsterixDB is a powerful new BDMS&#x2014;Big Data Management System&#x2014;that we hope may usher in a new era of much more declarative Big Data management. AsterixDB is powerful, so use it wisely, and remember: &#x201c;With great power comes great responsibility&#x2026;&#x201d; :-)</p>
869<p>Please e-mail the AsterixDB user group (users (at) asterixdb.incubator.apache.org) if you run into any problems or simply have further questions about the AsterixDB system, its features, or their proper use.</p></div>
870 </div>
871 </div>
872 </div>
873
874 <hr/>
875
876 <footer>
877 <div class="container-fluid">
878 <div class="row span12">Copyright &copy; 2015
879 <a href="http://www.apache.org/">The Apache Software Foundation</a>.
880 All Rights Reserved.
881
882 </div>
883
884 <?xml version="1.0" encoding="UTF-8"?>
885<div class="row-fluid">Apache AsterixDB, AsterixDB, Apache, the Apache
886 feather logo, and the Apache AsterixDB project logo are either
887 registered trademarks or trademarks of The Apache Software
888 Foundation in the United States and other countries.
889 All other marks mentioned may be trademarks or registered
890 trademarks of their respective owners.</div>
891
892
893 </div>
894 </footer>
895 </body>
896</html>