0% found this document useful (0 votes)
4 views59 pages

Arangodb - Hands-On Labs - Section b - Arangodb Development (2)

The document is a training manual for ArangoDB, detailing hands-on labs for environment setup and development. It includes sections on accessing environments, installation, and various labs covering different aspects of ArangoDB functionalities. The manual provides step-by-step instructions for tasks such as enabling remote access, securing deployments, and executing queries.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views59 pages

Arangodb - Hands-On Labs - Section b - Arangodb Development (2)

The document is a training manual for ArangoDB, detailing hands-on labs for environment setup and development. It includes sections on accessing environments, installation, and various labs covering different aspects of ArangoDB functionalities. The manual provides step-by-step instructions for tasks such as enabling remote access, securing deployments, and executing queries.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 59

A RANGODB

TRAINING
Hands On Labs

Version 0.7

ArangoDB | 415 Mission Street, Floor 37, San Francisco, CA


94104, United States
TABLE OF CONTENTS
1 ENVIRONMENT ACCESS / SETUP............................................................................... 3

1.1 CREDENTIALS.................................................................................................... 3
1.2 LICENSE KEY.................................................................................................... 3
1.3 LIST OF ENVIRONMENTS...................................................................................... 4

2 ARANGODB DEVELOPMENT.................................................................................... 5

2.1 INSTALLATION / ENVIRONMENT READINESS...............................................................5


2.1.1 LAB B-1: INSTALL YOUR BINARIES......................................................................................5
2.1.2 LAB B-2: ENABLE REMOTE ACCESS...................................................................................5
SECTION
ARANGODBBDEVELOPMENT
2.1.3 LAB B-3: SECURE YOUR DEPLOYMENT...............................................................................6
2.1.4 LAB B-4: SET YOUR ARANGODB LICENSE.........................................................................7
2.1.5 LAB B-5: WEBUI WALKTHROUGH.....................................................................................7
2.1.6 LAB B-6: STARTER INSTALL FOR CLUSTER........................................................................9
2.1.7 LAB B-7: DOCUMENT BASICS...........................................................................................11
2.1.8 LAB B-8: ARANGOSH BASICS..........................................................................................13
2.1.9 LAB B-9: REPLICAS AND WRITE CONCERN.......................................................................14
2.1.10 LAB B-10: REVISION ID.................................................................................................17
2.1.11 LAB B-11: OPTIMISTIC LOCKING / COMPARE AND SWAP / CONSISTENT ATOMIC UPDATES..18
2.1.12 LAB B-12: IMPORT TRAVEL DATASETS............................................................................18
2.1.13 LAB B-13: BASIC QUERYING..........................................................................................19
2.1.14 LAB B-14: SELECTIVE PROJECTIONS..............................................................................20
2.1.15 LAB B-15: BASIC DATE TIME........................................................................................20
2.1.16 LAB B-16: FILTERING....................................................................................................21
2.1.17 LAB B-17: SORTING......................................................................................................21
2.1.18 LAB B-18: CREATE DOCUMENTS...................................................................................22
2.1.19 LAB B-19: UPDATE DOCUMENTS...................................................................................25
2.1.20 LAB B-20: UPSERT DOCUMENTS..................................................................................26
2.1.21 LAB B-21: REPLACE DOCUMENTS..................................................................................28
2.1.22 LAB B-22: REPSERT DOCUMENTS.................................................................................29
2.1.23...................LAB B-23: IMPORT THE MOVIES DATASET
......................................................................................30
2.1.24.................................. LAB B-24: TERNARY OPERATOR
30
2.1.25 LAB B-25 STAR OPERATOR..........................................................................................30
2.1.26 LAB B-26 PARAMETER BINDING....................................................................................31
2.1.27 LAB B-27: COMPUTED VALUES....................................................................................32
2.1.28 LAB B-28: EXPLAIN AND PROFILE................................................................................34
2.1.29 LAB B-29: FIND THE 20 YOUNGEST ACTORS................................................................34

Page 1 of 59
2.1.30 LAB B-30: OPTIMIZE PERSON QUERIES.........................................................................34
2.1.31 LAB B-31: GEOSPATIAL QUERIES...................................................................................35
2.1.32 LAB B-32: LET AND JOINS...........................................................................................37
2.1.33 LAB B-33: JOIN MULTIPLE COLLECTIONS.....................................................................38
2.1.34 LAB B-34: SUBQUERIES...............................................................................................39
2.1.35 LAB B-35: AIRPORTS BY STATE...................................................................................40
2.1.36 LAB B-36: COUNT BY YEAR BORN................................................................................41
2.1.37 LAB B-37: AGGREGATE BY DECADE..............................................................................41
2.1.38 LAB B-38: FULL DOC COLLECTION..............................................................................42
2.1.39 LAB B-39: DISTINCT RELATIONS..................................................................................43
2.1.40 LAB B-40: ITERATE AND COUNT NON-COLLECTION DATA.............................................43
2.1.41 LAB B-41: L.O.T.R TRAVERSAL....................................................................................44
2.1.42 LAB B-42: CO-ACTORS OF VIGGO MORTENSON............................................................45
2.1.43 LAB B-43: K_SHORTEST_PATH...............................................................................46
2.1.44 LAB B-44: CREATE A SEARCH VIEW............................................................................46
2.1.45 LAB B-45 BASIC SEARCH............................................................................................50
2.1.46 LAB B-46 PHRASE SEARCH..........................................................................................52
2.1.47 LAB B-47 WORD PROXIMITY PHRASE SEARCH...............................................................54
2.1.48 LAB B-48 SCORING ALGORITHMS.................................................................................55

Page 2 of 59
ARANGODB TRAINING: HANDS-ON LABS

1 ENVIRONMENT ACCESS / SETUP

1.1 CREDENTIALS
Use the following credentials to log in to the lab environments.
# Environment Username Password Ports
1. ssh arangolabs $umm3r$un 22
2. Web UI root $umm3r$un 8529,
18529,
28529
38529,
45829
3. jupyter-labs @utumnL3@v3$ 8080

1.2LICENSE KEY
NOTE: Instructor to paste the latest license key here. The validUntil needs to be at
least until the last day of the training
{
"license": "license":
"eyJncmFudCI6ImV5Sm1aV0YwZFhKbGN5STZleUpsZUhCcGNtVnpJam
94TnpRNE56WXhNVGs1ZlN3aWJtOTBRbVZtYjNKbElqb2lNakF5TlMwd
05DMHlPRlF4TXpvMU56b3dNVm9pTENKdWIzUkJablJsY2lJNklqSXdN
alV0TURZdE1ERlVNRFk2TlRrNk5UbGFJaXdpYzNWaWFtVmpkQ0k2ZXl
KbGJXRnBiQ0k2SW5KaGFuVkFZbXgxWlhCaGJDNWpiMjBpZlN3aWFYTn
pkV1Z5SWpwN0ltTnZiWEJoYm5raU9pSkJjbUZ1WjI5RVFpQkhiV0pJS
Wl3aWJtRnRaU0k2SWxScGJHeHRZVzRnUkdsemMyVnNhMkZ0Y0NJc0lt
VnRZV2xzSWpvaWRHbHNiV0Z1TG1ScGMzTmxiR3RoYlhCQVlYSmhibWR
2WkdJdVkyOXRJbjBzSW1OMWMzUnZiV1Z5SWpwN0ltNWhiV1VpT2lKQ2
JIVmxjR0ZzSWl3aVpXNTJhWEp2Ym0xbGJuUWlPaUpRWVhKMGJtVnlJR
lJ5WVdsdWFXNW5JaXdpYjJWdElqb2lJbjBzSW5abGNuTnBiMjRpT2pG
OSIsInNpZ25hdHVyZSI6IkFuUm1jbnFyUGJYbHk2bmJIVkdyZVFHcGQ
3TTNaWHJhVnFoNHY3cS9ta2tNOVBwcFA0eGVlNTNyVXdMNk94bWFIZW
RNYTZGYkxpa3pyS3hFNWcvUTRHWHc2OTdqeUdhVVlpMGVkTnhXMDJ0Q

Page 3 of 59
ARANGODB TRAINING: HANDS-ON LABS

UVXS2RUZy9vV0lKQ2VnTUxTeTk0Vm4yT3VkWENiYVNUQkw5V3NRZjlK
MVJpRm5CZFhRTHZCc0cwd3ZQRzF2Y1VhZ1RwUUNqU20vUWExZXliZzB
0bDdaOUZEZXE3bWpiVmFncHVTZk1EV0orenF3VFFpWmJRbnc2eUxwbV
BLM1lkam94eXVLUDNVWWViM1kxRnQzTm9Fc01DdThxRGNHWVVSV1NyO
GwzclI2YWlBN2Z5dmhIZG8xYTFnUzRJYytqcERXdGc5bTl3K2swR2NW
c3JXRU5TaW10dFVMNUNIZmRGNFM4OEptU1Bpdz09In0=",
"validUntil": "2025-31-05T23:59:59Z",
"validUntilLocal": "5/31/2025",
"daysToExpiry": 24
}

1.3 LIST OF ENVIRONMENTS


Please enter your name against one of the nodes in the google sheet
here

Page 4 of 59
ARANGODB TRAINING: HANDS-ON LABS

2 ARANGODB DEVELOPMENT
2.1INSTALLATION / ENVIRONMENT READINESS

2.1.1LAB B-1: INSTALL YOUR BINARIES

1. Login to your instance you selected in Section 1.3 using the credentials
provided

ssh arangolabs@<your host/instance name>


2. Download / Install the binaries for your platform

rpm -i arangodb3e-<arangodb version>.x86_64.rpm


3. Start your arangodb instance

sudo systemctl start arangodb3


4. Verify the the arangodb instance has started correctly

sudo systemctl status arangodb3


5. Verify that the Web Interface is functional

curl -L http://localhost:8529
6. Next try accessing the arangodb instance remotely by entering the following
url into your browser

http://<your hostname>:8529
7. The host access should fail

2.1.2 LAB B-2: ENABLE REMOTE ACCESS

1. Make sure you are logged to your instance you selected in Section 1.3 using
the credentials provided
2. Enable remote access for your deployment by editing the arangod.conf

Page 5 of 59
ARANGODB TRAINING: HANDS-ON LABS

sudo vi /etc/arangodb3/arangod.conf
3. Edit the following line:
4. Original Line:

endpoint = tcp://127.0.0.1:8529
5. Edited Line:

endpoint = tcp://0.0.0.0:8529
6. Make sure you are editing the line which is not commented i.e. does not
start with #
7. Save your edits and quit
8. Start your arangodb instance

sudo systemctl restart arangodb3


9. Verify the the arangodb instance has started correctly

sudo systemctl status arangodb3


10. Verify that you can access the arangodb instance remotely by entering the
following url into your browser

http://<your hostname>:8529
11. Your access to the environment should now succeed

2.1.3 LAB B-3: SECURE YOUR DEPLOYMENT

1. Make sure you are logged to your instance you selected in Section 1.3 using
the credentials provided
2. Stop your arangodb instance

sudo systemctl stop arangodb3


3. Secure your instance with a new password

sudo arango-secure-installation
4. Specify and confirm your ‘root’ password once requested
5. Navigate to:

Page 6 of 59
ARANGODB TRAINING: HANDS-ON LABS

http://<your hostname>:8529
6. Login with the password you just specified for root

2.1.4 LAB B-4: SET YOUR ARANGODB LICENSE

1. Make sure you are logged to your instance you selected in Section 1.3 using
the credentials provided

ssh arangolabs@<your host/instance name>


2. Connect to the local arango instance using arangosh

arangosh
3. Enter your root password when prompted
4. Run the following command the prompt:

127.0.0.1:8529@_system> db._setLicense("<your license key>")


5. Note: The license key is the value of the attribute “license” in Section 1.2.
Please DO NOT select the whole JSON.

2.1.5 LAB B-5: WEBUI WALKTHROUGH

1. Connect to the WebUI of your instance

http://<your hostname>:8529

Page 7 of 59
ARANGODB TRAINING: HANDS-ON LABS

2. Validate your ArangoDB version on the bottom-left and top-left. The actual
version number may vary depending upon when this lab was conducted.

3. Verify the username being used and the database you are connected to.

4. Navigate to the Dashboard > Statistics look at the summary metrics being
presented
5. Navigate to the Dashboard > System Resources look at the summary
metrics being presented

Page 8 of 59
ARANGODB TRAINING: HANDS-ON LABS

6. Navigate to the Dashboard > Metrics and look at the counters being
presented.
7. These counters are also exposed via the Prometheus exporter for use in
tools such as Grafana, DataDog, etc.
8. Scroll down further to review the histograms
9. Explore other sections of the interface (you will need them later)

2.1.6 LAB B-6: STARTER INSTALL FOR CLUSTER

1. Use the starter tool (arangodb) to first create a jwt secret

arangodb create jwt-secret --secret=secrets/arangodb.secret


2. Restrict permissions on the file

chmod 400 secrets/arangodb.secret


3. Start the following commands in different terminals:
Starter 1:

arangodb --starter.data-dir=data/db1 --starter.mode=cluster --


auth.jwt-secret=secrets/arangodb.secret --
starter.port=18528 --starter.join=localhost:18528
Starter 2:

arangodb --starter.data-dir=data/db2 --starter.mode=cluster --


auth.jwt-secret=secrets/arangodb.secret --
starter.port=28528 --starter.join=localhost:18528
Starter 3:

arangodb --starter.data-dir=data/db3 --starter.mode=cluster --


auth.jwt-secret=secrets/arangodb.secret --
starter.port=38528 --starter.join=localhost:18528

4. The Starter uses the next few ports above the Starter port for the cluster
nodes. If you use port 8528 for the Starter
5. The Coordinator uses 8529 (=8528+1)
6. The DB-Server 8530 (=8528+2)

Page 9 of 59
ARANGODB TRAINING: HANDS-ON LABS

7. The Agent 8531 (=8528+3)


8. You should see a message similar to this once all the subprocesses are up:

9. The default password for starter instances is blank/empty password


10. You can change the password by logging into the webui
11. Alternatively, you can set the password using arangosh

arangosh --server.endpoint your-server-endpoint \


--server.password "" \
--javascript.execute-string
'require("@arangodb/users").update("root", "$umm3r$un");'
12. Next connect to the arangosh

arangosh --server.endpoint tcp://localhost:18529


13. Set your license key as in the previous labs

db._setLicense("<license key from your instructor>")


14. You should receive a 201 response with no error

15. Analyze the output of the following command

ps -ef|grep arangodb
16. You should be able to see the following:
a. 3 Starter processes
b. 3 DB Server Subprocesses
c. 3 Coordinator Subprocesses
d. 3 Agency subprocesses
17. Check the ptree of the primary agency process using

Page 10 of 59
ARANGODB TRAINING: HANDS-ON LABS

pstree <pid> -a
18. Note: To simulate the scenario, all processes and starters were started on
the same machine; this is great for development. In production, however,
you will end up deploying these processes on different machines.
19. At times, the agency, coordinator, and observers could all be on different
machines. You can make this differentiation by specifying --cluster.role
either as PRIMARY or DBSERVER or --cluster.role as COORDINATOR
20. Agency is activated using --agency.activate true

2.1.7 LAB B-7: DOCUMENT BASICS

1. Click DATABASES on the left Navigation


2. Click (+) Add Database
3. Specify the name of the database as test
4. Click Save

5. Click the _SYSTEM link on the top right to switch to the newly created
database

Page 11 of 59
ARANGODB TRAINING: HANDS-ON LABS

6. Choose test from the screen and click the green Select DB:test button

7. Create a collection
8. Click COLLECTIONS on the left navigation
9. Click (+) Add Collection
10. Specify the collection name as mycollection
11. Leave the rest as defaults and click Save

Page 12 of 59
ARANGODB TRAINING: HANDS-ON LABS

12. Run the following AQL query:

INSERT {fname: "John", lname: "Smith"} into mycollection return


NEW
13. You should see the following output

14. Copy the _id field from the result and use it to access the document and get
only the last name

RETURN DOCUMENT("mycollection/33780").lname
15. BONUS:
16. Navigate to COLLECTIONS
17. Click mycollection
18. Click Content
19. Review the documents created
20. Manually create a document using the (+) green sign on the top right corner

2.1.8 LAB B-8: ARANGOSH BASICS

1. You can either use the local arangosh installed on your training server or
choose to install the client tools locally on your machine. The client tools can
be found here:

Page 13 of 59
ARANGODB TRAINING: HANDS-ON LABS

https://arangodb.com/download/
2. Once you have installed the client you can use arangosh to connect to a
deployment
3. Simply typing arangosh will try and connect to a local deployment on 8529
4. To connect to a specific deployment use:

arangosh --server.endpoint <your host>:18529


5. You should see the following:

6. Additional help information can be obtained using:

arangosh --help
7. Let's go through a few basic usage steps
8. To create a database

localhost:18529@_system> db._createDatabase("mydb");
9. To use the created database

localhost:18529@_system> db._useDatabase("mydb");
10. To get additional help:

localhost:18529@_system> db._help();
11. To run a for loop:

localhost:18529@_system> for (var i = 0; i < 10; i ++) {


...> require("@arangodb").print("Hello world " + i + "!\n");
...> }
12. BONUS: (See: JavaScript API)
a. Try creating a collection mycollection in mydb
b. Get properties of the collection
c. Add 10 documents to mycollection

Page 14 of 59
ARANGODB TRAINING: HANDS-ON LABS

d. Run an AQL Query to get all documents in the collection


e. Truncate mycollection
f. Drop database mydb

2.1.9 LAB B-9: REPLICAS AND WRITE CONCERN

1. Login into the ArangoDB UI into the _system database


2. Create a database testdb with a default replication factor of 2

3. Switch into the newly created database by clicking _SYSTEM at the top right
corner

4. Select the database testdb in the upcoming screen

Page 15 of 59
ARANGODB TRAINING: HANDS-ON LABS

Page 16 of 59
ARANGODB TRAINING: HANDS-ON LABS

5. Next create a collection with a replication factor of 4 does it work? Why not?

6. Use arangosh to first switch to testdb

localhost:28529@_system> db._useDatabase("testdb")
7. Repeat the process via arangosh

localhost:28529@testdb> db._create("mycollection",
{ replicationFactor: 4 }, { enforceReplicationFactor: false
});
8. Does it work? Why? What's happening in the back end?
9. Next edit the collection properties and set the writeConcern to 4. Will it
work? Why or Why not?

Page 17 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.10 LAB B-10: REVISION ID

1. Switch back into testdb you created in the WebUI


2. Go to the Queries section and run the following query

INSERT {_key: "mykey",fname:"John",lname:"Smith"} into


mycollection
return NEW

10. Copy the _rev value from the returned table


11. Next, run the following query

RETURN DECODE_REV("_h_59XG6--A")
12. What does the output show? What timezone is the output?
NOTE: Revision Ids are meant for optimistic locking and debugging only please
do not build business logic on the decoded value, the implementation may
change in the future

Page 18 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.11 LAB B-11: OPTIMISTIC LOCKING / COMPARE AND SWAP /


CONSISTENT ATOMIC UPDATES

1. Run the following AQL query, by replacing your last obtained revision id in
<YOUR REVISION ID>

UPDATE { _key: "mykey", _rev: "<YOUR REVISION ID>" }


WITH { middlename: "Hammermill" } IN mycollection
OPTIONS { ignoreRevs: false }
RETURN NEW
2. Does the query work?
3. Run the query again without changing the revision id, does the query work?
Why ?
4. Run the same query by changing ignoreRevs: true but without changing
the revision id, does the query work? Why?
5. How would you implement concurrent writes with optimistic locking when
potentially the object has been overwritten before you try to commit it?

2.1.12 LAB B-12: IMPORT TRAVEL DATASETS

1. Create a new database called travel


6. Create three collections within the database
a. Document Collection: airports
b. Document Collection: points-of-interest
c. Edge Collection: flights
7. cd /home/arangolabs/examples/travel-jsonl
8. Import the airports.jsonl file into the airports collection:

arangoimport --server.endpoint tcp://<your host>:18529 \


--server.database travel \
--collection airports \
--server.username root \
--type json --file airports.jsonl

Page 19 of 59
ARANGODB TRAINING: HANDS-ON LABS

9. Import the points-of-interest.jsonl into the points-of-interest collection

arangoimport --server.endpoint tcp://localhost:18529 \


--server.database travel \
--collection points-of-interest \
--server.username root \
--type json --file points-of-interest.jsonl
10. Import the flights.jsonl into the flights collection

arangoimport --server.endpoint tcp://localhost:18529 \


--server.database travel \
--collection flights \
--server.username root \
--type json --file flights.jsonl

11. Confirm you see the following counts:


a. Documents:
i. 3375 for airports with no errors
ii. 51130 for points-of-interest with no errors
b. Edges: 286,463 for flights with no errors
12. BONUS:
a. You can alternatively restore a full dump using the arangorestore
command
b. Use the following:

arangorestore --server.database travel --server.username


root --create-database true --create-collection true
--input-directory ./travel-dump/ --server.endpoint
tcp://localhost:18529

2.1.13 LAB B-13: BASIC QUERYING

1. Query by _id:

return DOCUMENT('airports/SFO')
2. Query by _key:

return DOCUMENT('airports','SFO')

Page 20 of 59
ARANGODB TRAINING: HANDS-ON LABS

13. Read multiple documents by _id:

return DOCUMENT(['airports/SFO','airports/JFK'])
14. Read multiple documents by _key:

return DOCUMENT('airports',['SFO','OAK','JFK'])
15. Read multiple documents from different collections:

return DOCUMENT(['airports/SFO', 'flights/306630525'])

2.1.14 LAB B-14: SELECTIVE PROJECTIONS

1. Run the following query

LET airport = DOCUMENT('airports/DEN')


return {'name':airport.name,
'lat':airport.lat,
'long':airport.long,
'comment':'Third busiest airport in the world'}

2. Run the following query with KEEP

LET airport = DOCUMENT('airports/DEN')


return KEEP(airport, ['name','lat','long'])

3. Run the following query with MERGE

LET airport = DOCUMENT('airports/DEN')


return MERGE(KEEP(airport, ['name','lat','long']),{'comment':
'Third busiest airport in the world'})

2.1.15 LAB B-15: BASIC DATE TIME

1. Run the following query

RETURN DATE_NOW()
4. Run the following query

RETURN DATE_ISO8601(DATE_NOW())

Page 21 of 59
ARANGODB TRAINING: HANDS-ON LABS

5. Try the following

for flight in flights


return distinct
date_iso8601(flight.Year,flight.Month,flight.Day)

2.1.16 LAB B-16: FILTERING

1. Here is an example filter by a string attribute and equality operator

for flight in flights


filter flight.TailNum == 'N592ML'
return flight

2. Here is an example filter by a integer attribute and > operator

for flight in flights


filter flight.Distance > 600
return flight

3. You can also create compound/composite conditions

for flight in flights


filter flight.Distance > 600
filter flight.TailNum == 'N592ML'
return flight

4. The query above is exactly the same as a composite AND

for flight in flights


filter flight.Distance > 600 and flight.TailNum == 'N592ML'
return flight

5. The query above is NOT the same as the as query with OR


for flight in flights

filter flight.Distance > 600 or flight.TailNum == 'N592ML'


return flight

Page 22 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.17 LAB B-17: SORTING

1. Default behavior of the return is to simply return the results in the order the
were returned or consolidated

for airport in airports


return airport

2. Especially in a distributed database there is no guarantee of the order in


which the results will be returned. Your order of returned results may be
different from the next user without explicit sorting

3. A sort orders the results by a particular field or attribute

for airport in airports


sort airport.city
return airport

4. You can sort by multiple keys; lets sort by state first (ascending) and then
city (descending)

for airport in airports


sort airport.state asc, airport.city desc
return airport

5. Sorting has consequences on performance and memory utilization, so make


sure you have the right indexes in place for the best performance (more on
this later)

2.1.18 LAB B-18: CREATE DOCUMENTS

1. _key is autogenerated upon creation of a document when not specified


2. Create a document collection called scratch

Page 23 of 59
ARANGODB TRAINING: HANDS-ON LABS

3. Create an empty document using the following AQL query:

insert {} into scratch return NEW


4. The AQL query above creates and empty document, ArangoDB auto-
generates the key
5. The return NEW is optional, it returns the document that was
created. Note: The keyword NEW needs to be in capital case
6. You can view the results in either JSON or Table format
a. Table format:

b. JSON format:

Page 24 of 59
ARANGODB TRAINING: HANDS-ON LABS

7. You can also run the AQL query below, the created document will not be
returned:

insert {} into scratch


8. You can also create a document with additional attributes/fields (without
specifying an _key), ArangoDB auto-generates the key

insert {'field1': 'foo', 'field2': 'bar'} into scratch return


NEW

9. The following query is analogous to the previous query, quotes are not
required on the field names however are required on string values

insert {field1: 'foo', field2: 'bar'} into scratch return NEW


10. Unless there are spaces or special characters in the field names

o The following query will error / fail

insert {field1: 'foo', field2: bar, field 3: 'baz'} into scratch


return NEW

o The following corrected query will succeed

insert {field1: 'foo', field2: 'bar', 'field 3': 'baz'} into


scratch return NEW
11. Explicit keys / user-defined keys can also be set:

insert {'_key': 'foo-bar', field1: 'foo', 'field2': 'bar'} into


scratch return NEW

Page 25 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.19 LAB B-19: UPDATE DOCUMENTS

1. Let's create a document first which we can use to learn about all the
supported UPDATE operations update, replace, repset, upsert:

insert {'_key':'test-update','field1': 'foo','field2': 'bar',


'field3':'baz'} into scratch return NEW
2. Now that the document is added we can demonstrate all the operations on
the test document
3. You can update a document by directly specifying a key and the fields to
update:

update {_key: 'test-update'} WITH {'field1': "foo-updated",


'field4': 'new-field'} IN scratch RETURN NEW
4. We updated the value of field1 and simultaneously updated the document
with a new field field4. You should see the following result:

[
{
"_key": "test-update",
"_id": "scratch/test-update",
"_rev": "_gdrxqkm--_",
"field1": "foo-updated",
"field2": "bar",
"field3": "baz",
"field4": "new-field"
}
]

Page 26 of 59
ARANGODB TRAINING: HANDS-ON LABS

5. The following AQL is a short form version of the update with different fields,
but yields identical results

update {_key: 'test-update', 'field2': "bar-updated", 'field5':


'new-field'} IN scratch RETURN NEW
6. You should see the following results:

[
{
"_key": "test-update",
"_id": "scratch/test-update",
"_rev": "_gdr1Bzq--A",
"field1": "foo-updated",
"field2": "bar-updated",
"field3": "baz",
"filed4": "new-field",
"field5": "new-field"
}
]
7. Note:

o Update operations require a key


o As expected UPDATE does not overwrite fields unless explicitly
requested

2.1.20 LAB B-20: UPSERT DOCUMENTS

1. Upserts are used to insert-or-update, so a document will be inserted if one


doesn't exist otherwise it will be updated.

upsert {_key: 'test-upsert'}


insert {_key: 'test-upsert','field1': "foo", 'field2':
'bar','field3': 'baz'}
update {'field1': 'foo-updated','field4': 'new-field'} IN
scratch
return [OLD, NEW]

2. You should see the following result, null as the old document and the full
new document, indicating the document was inserted

Page 27 of 59
ARANGODB TRAINING: HANDS-ON LABS

[
[
null,
{
"_key": "test-upsert",
"_id": "scratch/test-upsert",
"_rev": "_gdslqDa---",
"field1": "foo",
"field2": "bar",
"field3": "baz"
}
]
]

CAUTION: If you do not specify the _key as a part of the upsert or


specified a different _key you will get unintended results (ArangoDB will
generate a new key)

3. Running the same AQL query multiple times you should see the following
results:

o Run #2: Original document, plus field1 is updated and field2 is added

[
[
{
"_key": "test-upsert",
"_id": "scratch/test-upsert",
"_rev": "_gdslqDa---",
"field1": "foo",
"field2": "bar",
"field3": "baz"
},
{
"_key": "test-upsert",
"_id": "scratch/test-upsert",
"_rev": "_gdslt_C---",
"field1": "foo-updated",
"field2": "bar",
"field3": "baz",
"field4": "new-field"
}

Page 28 of 59
ARANGODB TRAINING: HANDS-ON LABS

]
]

o Run 3 or more: Original document, plus field1 is updated and field2


is updated (No visible changes to the content)

[
[
{
"_key": "test-upsert",
"_id": "scratch/test-upsert",
"_rev": "_gdslt_C---",
"field1": "foo-updated",
"field2": "bar",
"field3": "baz",
"field4": "new-field"
},
{
"_key": "test-upsert",
"_id": "scratch/test-upsert",
"_rev": "_gdsl3Pe--_",
"field1": "foo-updated",
"field2": "bar",
"field3": "baz",
"field4": "new-field"
}
]
]
DANGER
Upsert operations can be run without specifying a _key in the
upsertExpression, but the behavior is undefined if more than one
document matches the upsert operation
Per the official documentation here:

In case at least one document in collection matches the


searchExpression, it will be updated using the updateExpression. When
more than one document in the collection matches the
searchExpression, it is undefined which of the matching documents will
be updated. It is therefore often sensible to make sure by other means
(such as unique indexes, application logic etc.) that at most one
document matches searchExpression.

Page 29 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.21 LAB B-21: REPLACE DOCUMENTS

1. Lets create a document first which we can use to learn about all the
supported UPDATE operations update, replace, repset, upsert:

insert {'_key':'test-replace','field1': 'foo','field2': 'bar',


'field3':'baz'} into scratch return NEW
2. Now that the document is added we can demonstrate all the operations on
the test document
3. You can replace a document by directly specifying a key and the fields:

replace {_key: 'test-replace'} WITH {'field6': "foo-updated",


'field7': 'new-field'} IN scratch RETURN NEW
or
replace {_key: 'test-replace', 'field6': "foo-updated",
'field7': 'new-field'} IN scratch RETURN NEW
4. Unlike Update, Replace will completely replace the contents of the
document with the provided document. You should see the following result:

[
{
"_key": "test-replace",
"_id": "scratch/test-replace",
"_rev": "_gdr8uVW--A",
"field6": "foo-updated",
"field7": "new-field"
}
]

NOTE:

o Replace operations require a key


o As expected a REPLACE completely overwrites the document with
the provided data

Page 30 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.22 LAB B-22: REPSERT DOCUMENTS

1. Repserts are used to insert-or-replace, so a document will be inserted if one


doesn't exist otherwise it will be replaced.

upsert {_key: 'test-repsert'}


insert {_key: 'test-repsert','field1': "foo", 'field2':
'bar','field3': 'baz'}
replace {'field1': 'foo-updated','field4': 'new-field'} IN
scratch
return [OLD, NEW]
2. Compare the results of the upsert and repsert to see the difference in
behavior
DANGER
Repsert operations can be run without specifying a _key in the
upsertExpression, but the behavior is undefined if more than one document
matches the upsert operation
Per the official documentation here:

In case at least one document in collection matches the searchExpression, it


will be updated using the updateExpression. When more than one document in
the collection matches the searchExpression, it is undefined which of the
matching documents will be updated. It is therefore often sensible to make
sure by other means (such as unique indexes, application logic etc.) that at
most one document matches searchExpression.

2.1.23 LAB B-23: IMPORT THE MOVIES DATASET

1. Create a movies database


6. Import the movies-dump into your instance

arangorestore --server.endpoint tcp://localhost:18529 \


--server.username root \
--server.database movies \
--input-directory "movies-dump" \
--create-database true \
--create-collection true

Page 31 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.24 LAB B-24: TERNARY OPERATOR

1. Ternary operator serves as an if else operator in AQL


7. Try a simple query

for p in Person
return MERGE(KEEP(p,'name'),{'born': p.born <= 1000 ? "**Bad
Data**": p.born})

2.1.25 LAB B-25 STAR OPERATOR

1. Star operators work great for filtering items within an array


8. Here is an example of re-shaping data using the star operator

let numbers = (for i in 1..20 return (i%2 == 0) ?


{ 'even': i} : { 'odd': i} )

return {"even numbers > 10": numbers[* FILTER CURRENT.even >


10].even,
"odd numbers > 10": numbers[* FILTER CURRENT.odd >
10].odd}

2.1.26 LAB B-26 PARAMETER BINDING

1. Parameter binding is a great way to create templatized queries and also to


prevent SQL (AQL) injections
9. Here is an using parameter binding.

for item in @@collection


FILTER item.name =~ @pattern
return item
10. Run the query by specifying the bind parameters: Person and Tim

Page 32 of 59
ARANGODB TRAINING: HANDS-ON LABS

11. What happens when you remove one of the @ from the binding?
12. Note: @@ is used for collections while @ is using for other singular
parameters
13. Here is an example of changing the @@ to @ and using an array instead

2.1.27 LAB B-27: COMPUTED VALUES

1. Create a collection called scratch


2. Navigate to the Computed Values section of the collection and enter the
following configuration

[
{"name": "dateISO8601",
"expression": "RETURN DATE_ISO8601(DATE_NOW())",
"overwrite": true,
"computeOn": ["insert","update", "replace"]
},
{"name": "dateEpoch",

Page 33 of 59
ARANGODB TRAINING: HANDS-ON LABS

"expression": "RETURN DATE_NOW()",


"overwrite": true,
"computeOn": ["insert","update", "replace"]
}
]
3. Clicking save should result in no errors

4. Next let's insert a few documents

for id in 1..10
insert {_key:CONCAT(id,"::doc")} into scratch
return NEW
5. You should see an output similar to this:

6. BONUS:
a. Try updating one or more documents. What do you see?

Page 34 of 59
ARANGODB TRAINING: HANDS-ON LABS

b. Change the computeOn settings and try the same. What difference
do you see?

2.1.28 LAB B-28: EXPLAIN AND PROFILE

1. Switch into the movies database


2. Open the query editor and run the following query:

FOR p IN Person
FILTER p.name == "Viggo Mortensen"
RETURN p
3. Find all the Jon* in the database

FOR p IN Person
FILTER p.name like 'Jon%'
RETURN p
4. Run the same query but sort it by year born
5. Run an explanation for each of those queries. What do you see?
6. Run a profile for each of those queries. What do you see?

2.1.29 LAB B-29: FIND THE 20 YOUNGEST ACTORS

1. Switch into the movies database


1. Edit the following query to get only the 20 youngest actors

FOR p IN Person
RETURN {name: p.name, born: p.born}
2. What do you need to do here? (Hint: you need to use LIMIT)
3. Extend what you just did to order the list by born followed by name
4. Run a profile for each of those queries. What do you see? What is the query
doing, and where??

Page 35 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.30 LAB B-30: OPTIMIZE PERSON QUERIES

1. Create a persistent index on name called idx_name by navigating to the


Person collection and then indexes

7. Profile the 3 queries again in the previous labs what do you see?
8. Create a composite index on name and born (name, born) and run a profile
what do you see?
9. Create an index on born ONLY and run a profile what do you see?

2.1.31 LAB B-31: GEOSPATIAL QUERIES

1. Switch into the ariports database

Page 36 of 59
ARANGODB TRAINING: HANDS-ON LABS

10. Let's get all the coordinates of airports in NY and CA

for airport in airports


filter airport.state == "CA" or airport.state=="NY"
return geo_point(airport.long, airport.lat)

11. The results in addition to JSON and Table formats, the data can be
displayed in Geospatial format on a map

12. Next let's find the airports to this location (< 10,000 meters)
a. Hertz Rental: 25 Bowery Bay Blvd, Queens, NY 11371
b. The Lat, Long: 40.76949,-73.88626
13. Find the GEO_DISTANCE between this location and all the other airports in
NY
a. Filter to all airport locations < 10,000 meters
b. Display the points on the map
14. Look at the profile of the query, is the query efficient
15. Create appropriate indexes to make the query more efficient
16. How are your queries more efficient with the indexes? What changed?
17. Solution:
a. Create a persistent index on state
b. Create a geospatial index on lat and long
c. Use GEO_DISTANCE (lat1,long1,lat2,long2) to calculate the distance
d. Filter to all airports < 10,000
e. Note: GEO_POINT is long,lat and NOT lat,long

Page 37 of 59
ARANGODB TRAINING: HANDS-ON LABS

for airport in airports


filter airport.state=="NY" and
distance(airport.lat,airport.long, 40.76949,-73.88626) <
10000
return GEO_POINT(airport.long,airport.lat)

2.1.32 LAB B-32: LET AND JOINS

1. Variables using let may be defined for various reasons, including code
readability
2. Sometimes it becomes complex or even impossible to put the whole query
in a single nested combination of for loops, filters, and sorts.
3. Often, it’s easier to extract some data separately. That’s where LET comes
in handy.
4. Say we want to find out options to get to SFO in 2 stops starting from Tampa
International (TPA) to San Francisco International (SFO), we could first find
out which airports can be reached directly from TPA, then for each of these
do a separate query to see which of those go to SFO.
5. Here is one way to get to the end goal:

let hops = (
for f IN flights
filter f._from == 'airports/TPA'

return distinct {"_from":f._from, "_to":f._to, "Distance":


f.Distance})

6. Now that we have all flights going out from Tampa International(TPA), we
can determine which flights go to San Francisco International (SFO)

for h IN hops
for f IN flights
filter f._to == 'airports/SFO'
filter f._from == h._to

Page 38 of 59
ARANGODB TRAINING: HANDS-ON LABS

let journey = {
"Path": CONCAT_SEPARATOR(" -> ",h._from,f._from,f._to),
"Distance Total": (h.Distance + f.Distance),
"Distance Leg1": h.Distance,
"Distance Leg2": f.Distance
}
sort journey.`Distance Total` desc, journey.`Distance Leg2`
desc, journey.`Distance Leg1` desc

return distinct journey

2.1.33 LAB B-33: JOIN MULTIPLE COLLECTIONS

1. Retrieve all actors along with the movies they acted in:
a. Persons are actors if they are linked to movies via documents in the
"Relation" collection with a "type" attribute value of "acted_in"
b. Persons and movies are referenced from the "Relation" collection via
the "_from" and "_to" attributes.
c. You will thus need to join the collections "Person", "Movie" and
"Relation"
d. Example:

{
"_id" : "Relation/8309",
"_from" : "Person/86", /* refers to Person collection */
"_to" : "Movie/82", /* refers to Movie collection */
"role" : "Wolf",
"type" : "acted_in" /* Want Relations of this type */
}
{
"_id" : "Person/86", /* refers to a Person */
"name" : "Harvey Keitel"
}
{
"_id" : "Movie/82", /* refers to a Movie */
"title" : "Pulp Fiction"
}

Page 39 of 59
ARANGODB TRAINING: HANDS-ON LABS

2. Switch into the movies database


1. Option 1:

FOR relation IN Relation


FILTER relation.type == 'acted_in'
FOR actor IN Person
FILTER actor._id == relation._from
FOR movie IN Movie
FILTER movie._id == relation._to
SORT actor.name
RETURN CONCAT(actor.name,
' -> acted in -> ',
movie.title)
2. Option 2:

FOR relation IN Relation


FILTER relation.type == 'acted_in'
SORT DOCUMENT(relation._from).name
RETURN CONCAT(DOCUMENT(relation._from).name,
' -> acted in -> ',
DOCUMENT(relation._to).title)

2.1.34 LAB B-34: SUBQUERIES

1. Retrieve all "Lord of the Rings" movies with their genres


a. Genres are stored in the "Genre" collection and are linked to Movies
via the "Relation" collection via edges that have a "type" value of
"has_genre"
b. Genres should be returned as lists
c. Example:

{
"_id" : "Relation/10406",
"_from" : "Movie/641", /*refers to Movie collection*/
"_to" : "Genre/17", /*refers to Genre collection*/
"type" : "has_genre"

Page 40 of 59
ARANGODB TRAINING: HANDS-ON LABS

{
"_id" : "Movie/641", /* this is the referred-to Movie*/
"title" : "The Lord of the Rings: The Return of the King"
}

{
"_id" : "Genre/17", /*this is the referred-to Genre*/
"name" : "Adventure"
}

3. Switch into the movies database


4. Run the following query:

FOR movie IN Movie


FILTER movie.title =~ "Lord.*Rings"
LET genres = (
FOR relation IN Relation
FILTER relation._from == movie._id &&
relation.type == 'has_genre'
FOR genre IN Genre
FILTER genre._id == relation._to
RETURN genre.name
)
RETURN {
title: movie.title,
genres
}

2.1.35 LAB B-35: AIRPORTS BY STATE

1. Switch into the airports database


2. Run the following query

for airport in airports


collect state = airport.state with count into total
return {
state: state,
'airports total': total
}

Page 41 of 59
ARANGODB TRAINING: HANDS-ON LABS

3. BONUS:
a. Order from the results from the most to the least airports

Page 42 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.36 LAB B-36: COUNT BY YEAR BORN

1. Switch into the movies database

2. Run the following query

FOR doc IN Person


COLLECT year = doc.born WITH COUNT INTO count
RETURN {
year,
count
}
3. You will see some bad data in the results. How do you filter that?
4. BONUS:
a. Next you want only years where the count of people born that year is
>=10 how would you accomplish that?
5. Solution:

FOR doc IN Person


FILTER doc.born >= 1900
COLLECT year = doc.born WITH COUNT INTO count
FILTER count > 10
SORT count DESC
RETURN {
year,
count
}

2.1.37 LAB B-37: AGGREGATE BY DECADE

1. Switch into the movies database

2. How would you aggregate by decade, Hint: You need to use min and max

3. Solution:

Page 43 of 59
ARANGODB TRAINING: HANDS-ON LABS

FOR doc IN Person


COLLECT decade = FLOOR(doc.born / 10)
AGGREGATE min = MIN(doc.born),
max = MAX(doc.born),
count = COUNT(doc)
RETURN {
decade: CONCAT(min, ' to ', max),
count
}

2.1.38 LAB B-38: FULL DOC COLLECTION

1. Switch into the movies database


2. Collection of the full doc

FOR doc IN Person


COLLECT year = doc.born INTO personsByYear
RETURN {
year,
personsByYear
}
3. How would you project only the name?
4. Option 1:

FOR doc IN Person


COLLECT year = doc.born INTO personsByYear = doc.name
RETURN {
year,
personsByYear
}
5. Option 2:

FOR doc IN Person


COLLECT year = doc.born INTO personsByYear = doc.name
RETURN {
year,
personsByYear: personsByYear[*].doc.name
}

Page 44 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.39 LAB B-39: DISTINCT RELATIONS

1. Switch into the movies database


3. The following query generates the list of all types for every relation

FOR doc IN Relation


RETURN doc.type
4. The following query generates the list of all DISTINCT types for every
relation

FOR doc IN Relation


RETURN DISTINCT doc.type

2.1.40 LAB B-40: ITERATE AND COUNT NON-COLLECTION


DATA

1. Group all movies in the "Movie" collection by the following duration ranges:

a. less than 60 minutes


b. 60 - 75 minutes
c. 75 - 90 minutes
d. 90 - 120 minutes
e. 120 - 150 minutes
f. more than 150 minutes
4. The above groups should be non-overlapping, so "60 - 75" means the lower
bound of 60 is inclusive, but the upper bound of 75 is exclusive.
a. For each group, report the number of movies found, plus the
minimum and maximum duration
b. Groups for which there are no movies found should still be reported.

Page 45 of 59
ARANGODB TRAINING: HANDS-ON LABS

5. SOLUTION:

FOR duration IN [ [0, 60 ], [ 60, 75 ], [ 75, 90 ], [ 90, 120 ],


[ 120, 150 ], [150, 999] ]
LET group = (
FOR movie IN Movie
FILTER movie.duration >= duration[0] &&
movie.duration < duration[1]
COLLECT AGGREGATE count = COUNT(movie),
min = MIN(movie.duration),
max = MAX(movie.duration)
RETURN {
count,
min,
max
}
)[0]

RETURN {
duration: CONCAT(duration[0], ' - ', duration[1]),
count: group.count,
min: group.min,
max: group.max
}

2.1.41 LAB B-41: L.O.T.R TRAVERSAL

1. Retrieve all "Lord of the Rings" movies with their direct relations.
a. Start by iterating over the "Movies" collection to find the relevant
movies, and for each of them, start a traversal with the direction
"ANY" on the "Relation" collection.
b. For each relation, return the type of the relation plus the related
document
5. Switch to the movies database

FOR movie IN Movie


FILTER movie.title =~ "Lord.*Rings"
FOR v, e, p IN ANY movie._id Relation
RETURN {

Page 46 of 59
ARANGODB TRAINING: HANDS-ON LABS

title: movie.title,
relation: {
type: e.type,
value: v
}
}
6. The above query will return an error , why?
7. Add the following to the query at the very beginning:

WITH Keyword, Genre, Person, Movie

2.1.42 LAB B-42: CO-ACTORS OF VIGGO MORTENSON

1. Write an AQL query that finds all the co-actors of Viggo Mortensen
a. First, try to find all the movies that Viggo Mortensen acted in
b. Then, find other persons who acted in the same movies.
2. Step 1: Get the Actor Id

/* Step 1 */
LET viggo = (
FOR actor IN Person
FILTER actor.name =~ "^Viggo"
RETURN actor._id
)[0]

RETURN viggo
3. Step 2: Get the movies with Viggo

WITH Movie // Need this reference for Step 2

LET viggo = (
FOR actor IN Person
FILTER actor.name =~ "^Viggo"
RETURN actor._id
)[0]

LET moviesWithViggo = (
FOR v,e,p IN OUTBOUND viggo Relation
FILTER p.edges[0].type == 'acted_in'
RETURN v._id

Page 47 of 59
ARANGODB TRAINING: HANDS-ON LABS

RETURN moviesWithViggo
2. Step 3: Get all the Relations for acted_in

/*Everything put together*/


WITH Movie

LET viggo = (
FOR actor IN Person
FILTER actor.name =~ "^Viggo"
RETURN actor._id
)[0]

LET moviesWithViggo = (
FOR v,e,p IN OUTBOUND viggo Relation
FILTER p.edges[0].type == 'acted_in'
RETURN v._id
)
FOR movie IN moviesWithViggo
FOR v,e,p IN INBOUND movie Relation
FILTER p.edges[0].type == 'acted_in'
FILTER v._id != viggo
RETURN DISTINCT v.name

2.1.43 LAB B-43: K_SHORTEST_PATH

1. Let's determine the shortest paths between TPA and SFO


2. To get the shortest path, you can use the following query:

with airports
for path IN outbound all_shortest_paths 'airports/TPA' to
'airports/SFO' flights
options {
weightAttribute: "Distance"
}
return path

Page 48 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.44 LAB B-44: CREATE A SEARCH VIEW

1. We are going to use the point-of-interest collection to learn about search


views
2. Follow the steps to create the wikiVoyage view
a. Click VIEWS
b. Click (+) Add View
c. Specify the name of the view as wikiVoyage
d. Click Create

3. Next we need to edit the view to add some analyzers


a. Click the view name wikiVoyage to edit the view

Page 49 of 59
ARANGODB TRAINING: HANDS-ON LABS

4. We then link the view to the points-of-interest collection


a. Click Links
b. Choose points-of-interest as the collection
c. Click Save View

5. The view is now ready for use in queries


6. Let's configure the analyzers for the document and fields
a. Click JSON
b. Edits the links value of the JSON with the following content:

"links": {
"points-of-interest": {
"analyzers": [
"identity"
],
"fields": {
"description": {

Page 50 of 59
ARANGODB TRAINING: HANDS-ON LABS

"analyzers": [
"text_en",
"identity"
]
},
"title": {
"analyzers": [
"text_en",
"identity"
]
}
},
"includeAllFields": true,
"storeValues": "none",
"trackListPositions": false
}
}

c. Click Save View to save the view

Page 51 of 59
ARANGODB TRAINING: HANDS-ON LABS

Page 52 of 59
ARANGODB TRAINING: HANDS-ON LABS

2.1.45 LAB B-45 BASIC SEARCH

1. Identity search requires the complete content to match


2. Run the following search

for doc IN wikiVoyage


search doc.title == "San Francisco International Airport"
return doc
3. You should see the following results:

[
{
"_key": "20130659",
"_id": "points-of-interest/20130659",
"_rev": "_giji-7S---",
"alt": "{{IATA|SFO}}",
"article": "San Francisco",
"description": "Located about 10&nbsp;mi
(16&nbsp;km) south of the city, is the Bay Area's major
international airport (and one of the busiest in the
nation) and has numerous passenger amenities including a
wide range of food and drink establishments, shopping,
baggage storage, public showers, a medical clinic, and
assistance for lost or stranded travelers and military
personnel. SFO has four terminals; as a rule of thumb,
Alaska Airlines and American Airlines use Terminal 2,
United Airlines has Terminal 3, most other domestic
carriers use Terminal 1, and all foreign airlines use the
International Terminal. SFO is infamous for its weather
delays, so check if Oakland Airport has service from your
origin as well. Oakland is closer to Downtown San
Francisco than SFO is and fog free.",
"lastEdit": "2019-09-02",
"latitude": 37.618889,
"longitude": -122.375,
"phone": "+1-800-435-9736",
"title": "San Francisco International Airport",
"type": "go",
"url": "https://FlySFO.com",
"wikidata": "Q8688"
}

Page 53 of 59
ARANGODB TRAINING: HANDS-ON LABS

4. If you run the following search instead

for doc IN wikiVoyage


search doc.title == "San Francisco"
return doc

5. Your results will be different

[
{
"_key": "20131814",
"_id": "points-of-interest/20131814",
"_rev": "_gijiAAK--h",
"article": "James Bond tourism",
"description": "Featured in ''A View to a Kill''
(1985).",
"directions": "United States",
"latitude": 37.75769,
"longitude": -122.47261,
"title": "San Francisco",
"type": "other"
},
{
"_key": "20133355",
"_id": "points-of-interest/20133355",
"_rev": "_gijhmA2--A",
"article": "Marvel Cinematic Universe",
"description": "The majority of the film takes
place here.",
"directions": "California, United States",
"latitude": 37.801944,
"longitude": -122.418889,
"title": "San Francisco",
"type": "other",
"wikidata": "Q62"
},
{
"_key": "20133872",
"_id": "points-of-interest/20133872",
"_rev": "_gijhmIu--C",
"article": "Chocolate",
"description": "A city with a thriving chocolate

Page 54 of 59
ARANGODB TRAINING: HANDS-ON LABS

scene. Home of Ghirardelli Chocolate.",


"image": "Ghirardelli Chocolate Shop Inside, SF,
CA, jjron 25.03.2012.jpg",
"lastEdit": "2018-12-06",
"latitude": 37.766667,
"longitude": -122.433333,
"title": "San Francisco",
"type": "maroon",
"wikidata": "Q62"
}
]

6. The default search is exact search, for the full string with == and is case
sensitive
7. Is recommended to specify the analyzer being used, so that the context is
clear to the developer

for doc IN wikiVoyage


search analyzer(doc.title == "San Francisco", "identity")
return doc

2.1.46 LAB B-46 PHRASE SEARCH

1. If you need to search for a phrase in the document, you will instead use the
following:

for doc IN wikiVoyage


search phrase(doc.title, "San Francisco", "text_en")
return doc
2. Here is a snippet of the results you should see:

[
{
"_key": "20130050",
"_id": "points-of-interest/20130050",
"_rev": "_giji-Cm-AD",
"address": "114 East Spain Street, Sonoma",
"alt": "Sonoma State Historic Park",
"article": "El Camino Real",
"description": "Founded in 1823 as the last of the
Spanish missions, in part by Mariano Vallejo to check the

Page 55 of 59
ARANGODB TRAINING: HANDS-ON LABS

Russian's impact in Northern California. Site of the first


vineyard in Sonoma County. This is where American settlers
began their uprising against the Mexicans known as the Bear
Flag Revolt of 1846. It was bought by the California
Historic Landmarks League in 1903 and restored in 1913.
Though it was the last mission, it was the third structure
in California to be designated a State Historic Landmark",
"hours": "10AM-5PM",
"image": "Mission San Francisco Solano - Sonoma CA
USA (12).JPG",
"latitude": 38.294029,
"longitude": -122.455956,
"phone": "+1 707 938-9560",
"title": "Mission San Francisco Solano",
"type": "see",
"url": "http://www.parks.ca.gov/?page_id=479"
},
{
"_key": "20130659",
"_id": "points-of-interest/20130659",
"_rev": "_giji-7S---",
"alt": "{{IATA|SFO}}",
"article": "San Francisco",
"description": "Located about 10&nbsp;mi
(16&nbsp;km) south of the city, is the Bay Area's major
international airport (and one of the busiest in the
nation) and has numerous passenger amenities including a
wide range of food and drink establishments, shopping,
baggage storage, public showers, a medical clinic, and
assistance for lost or stranded travelers and military
personnel. SFO has four terminals; as a rule of thumb,
Alaska Airlines and American Airlines use Terminal 2,
United Airlines has Terminal 3, most other domestic
carriers use Terminal 1, and all foreign airlines use the
International Terminal. SFO is infamous for its weather
delays, so check if Oakland Airport has service from your
origin as well. Oakland is closer to Downtown San
Francisco than SFO is and fog free.",
"lastEdit": "2019-09-02",
"latitude": 37.618889,
"longitude": -122.375,
"phone": "+1-800-435-9736",
"title": "San Francisco International Airport",
"type": "go",
"url": "https://FlySFO.com",

Page 56 of 59
ARANGODB TRAINING: HANDS-ON LABS

"wikidata": "Q8688"
},
{
"_key": "20130865",
"_id": "points-of-interest/20130865",
"_rev": "_giji_HG--1",
"address": "1 Old Bayshore Highway",
"article": "San Francisco International Airport",
"image": "Millbrae, CA, USA - panoramio.jpg",
"lastEdit": "2019-10-05",
"latitude": 37.603429,
"longitude": -122.376155,
"phone": "+1 650 692-3500",
"title": "The Westin San Francisco Airport",
"type": "sleep",
"url":
"https://www.marriott.com/hotels/travel/sfowi-the-westin-
san-francisco-airport/"
},
{
"_key": "20130866",
"_id": "points-of-interest/20130866",
"_rev": "_giji_HG-_D",
"address": "401 E Millbrae Ave",
"article": "San Francisco International Airport",
"image": "Aloft San Francisco Airport.jpg",
"lastEdit": "2019-10-05",
"latitude": 37.603164,
"longitude": -122.377678,
"phone": "+1 650 443-5500",
"title": "Aloft San Francisco Airport",
"type": "sleep",
"url":
"https://www.marriott.com/hotels/travel/sfoal-aloft-san-
francisco-airport/"
},
...

2.1.47 LAB B-47 WORD PROXIMITY PHRASE SEARCH

1. Run the following phrase search

Page 57 of 59
ARANGODB TRAINING: HANDS-ON LABS

for p in wikiVoyage
search Phrase(p.title,"Aloft",2,"Airport",'text_en')
limit 10
return p
3. Those are too few results, what do you need to do to get more results?
4. Hint: Try and use additional OR conditions to find more results, try adding
Hilton to your query
5. SOLUTION:

for p in wikiVoyage
search Phrase(p.title,"Aloft",2,"Airport",'text_en') or
Phrase(p.title,"Aloft",1,"Airport",'text_en') or
Phrase(p.title,"Hilton",1,"Airport",'text_en') or
Phrase(p.title,"Hilton",2,"Airport",'text_en')

return p

2.1.48 LAB B-48 SCORING ALGORITHMS

1. Try running the following query, see the results ranking:

LET keywords = TOKENS (


'airport flight jet air aircraft runway domestic
international plane carrier aviation', 'text_en')

FOR p IN wikiVoyage
SEARCH ANALYZER ( p.description IN keywords, 'text_en')
SORT BM25 (p) DESC
LIMIT 10
RETURN p
2. Change the algorithm to TFIDF do you see any difference in the ranking?

Page 58 of 59

You might also like