diff --git a/notebooks/ArangoDB_GOT_Tutorial_magic.ipynb b/notebooks/ArangoDB_GOT_Tutorial_magic.ipynb new file mode 100644 index 0000000..c29afa7 --- /dev/null +++ b/notebooks/ArangoDB_GOT_Tutorial_magic.ipynb @@ -0,0 +1,402 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "ArangoDB_GOT_Tutorial.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "7vn7qQcVHejm", + "colab_type": "text" + }, + "source": [ + "![alt text](https://www.arangodb.com/wp-content/uploads/2013/03/ArangoDB-logo.png)\n", + "Welcome to the ArangoDB Games OF Thrones Tutorial. \n", + "This is an introduction to ArangoDB’s query language AQL, built around a small dataset of characters from the novel and fantasy drama television series Game of Thrones (as of season 1). It includes character traits in two languages, some family relations, and last but not least a small set of filming locations, which makes for an interesting mix of data to work with." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lPKaqikzz60n", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# Install required packages\n", + "!pip install python-arango\n", + "\n", + "import requests\n", + "import json\n", + "from arango import ArangoClient\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ImZHgsvrJ8pQ", + "colab_type": "text" + }, + "source": [ + "Before we get started we need to create a temporary database with our [managed database service Oasis](https://cloud.arangodb.com). Please note the database will be automatically deleted after 2 hours." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "un7CV5mf0M1X", + "colab_type": "code", + "colab": {} + }, + "source": [ + "url = 'https://a0434a558688.arangodb.cloud:8529/_db/_system/tutorialDB/tutorialDB'\n", + "headers = {'Content-Type': 'application/json'}\n", + "payload = {'username': 'testFromColab'}\n", + "getDB = requests.post(url, headers=headers, data=json.dumps({'':''}))\n", + "results = getDB.json()\n", + "print(results)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E3v4R-SHNuAU", + "colab_type": "text" + }, + "source": [ + "Let us connect to our temporary database:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9L7fzpJW8Xcd", + "colab_type": "code", + "colab": {} + }, + "source": [ + "\n", + "host = 'https://' + results['hostname'] + ':' + str(results['port'])\n", + "client = ArangoClient(hosts=host)\n", + "print(client)\n", + "db = client.db(results['dbName'], username=results['username'], password=results['password'])\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nsHRCB7eQ3Vq", + "colab_type": "text" + }, + "source": [ + "\n", + "With the above credentials we can also login into the ArangoDB UI: https://a0434a558688.arangodb.cloud:8529/:\n", + "\n", + "![alt text](https://www.arangodb.com/docs/stable/images/loginView.png)" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "PApkAUfp-sel", + "colab_type": "code", + "colab": {} + }, + "source": [ + "aql = db.aql\n", + "\n", + "if db.has_collection('Characters'):\n", + " Characters = db.collection('Characters')\n", + "else:\n", + " Characters = db.create_collection('Characters')\n", + "\n", + "cursor = aql.execute(\n", + " 'INSERT {'\n", + " '\"name\": \"Ned\",'\n", + " '\"surname\": \"Stark\",'\n", + " '\"alive\": true,'\n", + " '\"age\": 41,'\n", + " '\"traits\": [\"A\",\"H\",\"C\",\"N\",\"P\"]'\n", + " '} INTO Characters'\n", + ")\n", + "\n", + "\n", + "print(db[\"Characters\"])\n", + "print([doc['_key'] for doc in cursor])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "X43Lso_CqbgC", + "colab_type": "code", + "colab": {} + }, + "source": [ + "from IPython.core.magic import (register_line_magic,\n", + " register_cell_magic)\n", + "from io import StringIO\n", + "import os\n", + "\n", + "@register_cell_magic\n", + "def aql(line, cell):\n", + "\n", + " host = 'https://' + os.environ['HOSTNAME'] + ':' + str(os.environ['PORT'])\n", + " client = ArangoClient(hosts=host)\n", + " db = client.db(os.environ['DB_NAME'], username=os.environ['USERNAME'], password=os.environ['PASSWORD'])\n", + " # We create a string buffer containing the\n", + " # contents of the cell.\n", + " query = cell\n", + " #print(query)\n", + " # Return cursor\n", + " return db.aql.execute(query)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sR_JK9eWun7Y", + "colab_type": "text" + }, + "source": [ + "Just use the AQL magic" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WMc1Uc_awkRi", + "colab_type": "code", + "colab": {} + }, + "source": [ + "os.environ['DB_NAME'] = results['dbName']\n", + "os.environ['USERNAME'] = results['username']\n", + "os.environ['PASSWORD'] = results['password']\n", + "os.environ['HOSTNAME'] = results['hostname']\n", + "os.environ['PORT'] = str(results['port'])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab_type": "code", + "id": "QbvbdDyfyyjg", + "colab": {} + }, + "source": [ + "%env DB_NAME TUT2mwshppu8um4ogr0390boo\n", + "%env USERNAME TUTxjdsn0ndw17vh9rj4xdar\n", + "%env PASSWORD TUTyj4d51i3brfv456rr00nol\n", + "%env HOSTNAME a0434a558688.arangodb.cloud \n", + "%env PORT 8529" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Mk5wvIcSspAn", + "colab_type": "code", + "colab": {} + }, + "source": [ + "%%aql \n", + " FOR c IN Characters\n", + " FILTER c.name == \"Ned\"\n", + " RETURN c" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "n9Q4dNAXuafL", + "colab_type": "code", + "colab": {} + }, + "source": [ + "cursor = _\n", + "print([doc['_key'] for doc in cursor])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "JDaohKLHrvxO", + "colab_type": "code", + "colab": {} + }, + "source": [ + "cursor = aql.execute(\"\"\"FOR c IN Characters\n", + " FILTER c.name == \"Ned\"\n", + " RETURN c\"\"\")\n", + "print([doc['_key'] for doc in cursor])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "iLwNVOp-CH9C", + "colab_type": "text" + }, + "source": [ + "Let’s add a bunch of other characters in a single query:\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Weaf_1lMCJ7-", + "colab_type": "code", + "colab": {} + }, + "source": [ + "cursor = aql.execute(\n", + "'LET data = [\\\n", + " { \"name\": \"Robert\", \"surname\": \"Baratheon\", \"alive\": false, \"traits\": [\"A\",\"H\",\"C\"] },\\\n", + " { \"name\": \"Jaime\", \"surname\": \"Lannister\", \"alive\": true, \"age\": 36, \"traits\": [\"A\",\"F\",\"B\"] },\\\n", + " { \"name\": \"Catelyn\", \"surname\": \"Stark\", \"alive\": false, \"age\": 40, \"traits\": [\"D\",\"H\",\"C\"] },\\\n", + " { \"name\": \"Cersei\", \"surname\": \"Lannister\", \"alive\": true, \"age\": 36, \"traits\": [\"H\",\"E\",\"F\"] },\\\n", + " { \"name\": \"Daenerys\", \"surname\": \"Targaryen\", \"alive\": true, \"age\": 16, \"traits\": [\"D\",\"H\",\"C\"] },\\\n", + " { \"name\": \"Jorah\", \"surname\": \"Mormont\", \"alive\": false, \"traits\": [\"A\",\"B\",\"C\",\"F\"] },\\\n", + " { \"name\": \"Petyr\", \"surname\": \"Baelish\", \"alive\": false, \"traits\": [\"E\",\"G\",\"F\"] },\\\n", + " { \"name\": \"Viserys\", \"surname\": \"Targaryen\", \"alive\": false, \"traits\": [\"O\",\"L\",\"N\"] },\\\n", + " { \"name\": \"Jon\", \"surname\": \"Snow\", \"alive\": true, \"age\": 16, \"traits\": [\"A\",\"B\",\"C\",\"F\"] },\\\n", + " { \"name\": \"Sansa\", \"surname\": \"Stark\", \"alive\": true, \"age\": 13, \"traits\": [\"D\",\"I\",\"J\"] },\\\n", + " { \"name\": \"Arya\", \"surname\": \"Stark\", \"alive\": true, \"age\": 11, \"traits\": [\"C\",\"K\",\"L\"] },\\\n", + " { \"name\": \"Robb\", \"surname\": \"Stark\", \"alive\": false, \"traits\": [\"A\",\"B\",\"C\",\"K\"] },\\\n", + " { \"name\": \"Theon\", \"surname\": \"Greyjoy\", \"alive\": true, \"age\": 16, \"traits\": [\"E\",\"R\",\"K\"] },\\\n", + " { \"name\": \"Bran\", \"surname\": \"Stark\", \"alive\": true, \"age\": 10, \"traits\": [\"L\",\"J\"] },\\\n", + " { \"name\": \"Joffrey\", \"surname\": \"Baratheon\", \"alive\": false, \"age\": 19, \"traits\": [\"I\",\"L\",\"O\"] },\\\n", + " { \"name\": \"Sandor\", \"surname\": \"Clegane\", \"alive\": true, \"traits\": [\"A\",\"P\",\"K\",\"F\"] },\\\n", + " { \"name\": \"Tyrion\", \"surname\": \"Lannister\", \"alive\": true, \"age\": 32, \"traits\": [\"F\",\"K\",\"M\",\"N\"] },\\\n", + " { \"name\": \"Khal\", \"surname\": \"Drogo\", \"alive\": false, \"traits\": [\"A\",\"C\",\"O\",\"P\"] },\\\n", + " { \"name\": \"Tywin\", \"surname\": \"Lannister\", \"alive\": false, \"traits\": [\"O\",\"M\",\"H\",\"F\"] },\\\n", + " { \"name\": \"Davos\", \"surname\": \"Seaworth\", \"alive\": true, \"age\": 49, \"traits\": [\"C\",\"K\",\"P\",\"F\"] },\\\n", + " { \"name\": \"Samwell\", \"surname\": \"Tarly\", \"alive\": true, \"age\": 17, \"traits\": [\"C\",\"L\",\"I\"] },\\\n", + " { \"name\": \"Stannis\", \"surname\": \"Baratheon\", \"alive\": false, \"traits\": [\"H\",\"O\",\"P\",\"M\"] },\\\n", + " { \"name\": \"Melisandre\", \"alive\": true, \"traits\": [\"G\",\"E\",\"H\"] },\\\n", + " { \"name\": \"Margaery\", \"surname\": \"Tyrell\", \"alive\": false, \"traits\": [\"M\",\"D\",\"B\"] },\\\n", + " { \"name\": \"Jeor\", \"surname\": \"Mormont\", \"alive\": false, \"traits\": [\"C\",\"H\",\"M\",\"P\"] },\\\n", + " { \"name\": \"Bronn\", \"alive\": true, \"traits\": [\"K\",\"E\",\"C\"] },\\\n", + " { \"name\": \"Varys\", \"alive\": true, \"traits\": [\"M\",\"F\",\"N\",\"E\"] },\\\n", + " { \"name\": \"Shae\", \"alive\": false, \"traits\": [\"M\",\"D\",\"G\"] },\\\n", + " { \"name\": \"Talisa\", \"surname\": \"Maegyr\", \"alive\": false, \"traits\": [\"D\",\"C\",\"B\"] },\\\n", + " { \"name\": \"Gendry\", \"alive\": false, \"traits\": [\"K\",\"C\",\"A\"] },\\\n", + " { \"name\": \"Ygritte\", \"alive\": false, \"traits\": [\"A\",\"P\",\"K\"] },\\\n", + " { \"name\": \"Tormund\", \"surname\": \"Giantsbane\", \"alive\": true, \"traits\": [\"C\",\"P\",\"A\",\"I\"] },\\\n", + " { \"name\": \"Gilly\", \"alive\": true, \"traits\": [\"L\",\"J\"] },\\\n", + " { \"name\": \"Brienne\", \"surname\": \"Tarth\", \"alive\": true, \"age\": 32, \"traits\": [\"P\",\"C\",\"A\",\"K\"] },\\\n", + " { \"name\": \"Ramsay\", \"surname\": \"Bolton\", \"alive\": true, \"traits\": [\"E\",\"O\",\"G\",\"A\"] },\\\n", + " { \"name\": \"Ellaria\", \"surname\": \"Sand\", \"alive\": true, \"traits\": [\"P\",\"O\",\"A\",\"E\"] },\\\n", + " { \"name\": \"Daario\", \"surname\": \"Naharis\", \"alive\": true, \"traits\": [\"K\",\"P\",\"A\"] },\\\n", + " { \"name\": \"Missandei\", \"alive\": true, \"traits\": [\"D\",\"L\",\"C\",\"M\"] },\\\n", + " { \"name\": \"Tommen\", \"surname\": \"Baratheon\", \"alive\": true, \"traits\": [\"I\",\"L\",\"B\"] },\\\n", + " { \"name\": \"Jaqen\", \"surname\": \"Hghar\", \"alive\": true, \"traits\": [\"H\",\"F\",\"K\"] },\\\n", + " { \"name\": \"Roose\", \"surname\": \"Bolton\", \"alive\": true, \"traits\": [\"H\",\"E\",\"F\",\"A\"] },\\\n", + " { \"name\": \"The High Sparrow\", \"alive\": true, \"traits\": [\"H\",\"M\",\"F\",\"O\"] }\\\n", + " ]\\\n", + " FOR d IN data INSERT d INTO Characters'\n", + " )" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u_ftzlE3D0Po", + "colab_type": "text" + }, + "source": [ + "The LET keyword defines a variable with name data and an array of objects as value, so LET variableName = valueExpression and the expression being a literal array definition like [ {...}, {...}, ... ].\n", + "\n", + "FOR variableName IN expression is used to iterate over each element of the data array. In each loop, one element is assigned to the variable d. This variable is then used in the INSERT statement instead of a literal object definition. What is does is basically:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Bk-EvGk-GeFH", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# Print all characters from Python Driver\n", + "for character in db.collection('Characters'):\n", + " print(\"- %s\" % character['name'])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Scw6LAZZD06P", + "colab_type": "code", + "colab": {} + }, + "source": [ + "cursor = aql.execute('INSERT {'\n", + " '\"name\": \"Robert\",'\n", + " '\"surname\": \"Baratheon\",'\n", + " '\"alive\": false,'\n", + " '\"traits\": [\"A\",\"H\",\"C\"]'\n", + "'} INTO Characters'\n", + ")\n", + "cursor = aql.execute(\n", + " 'INSERT {'\n", + " '\"name\": \"Jaime\",'\n", + " '\"surname\": \"Lannister\",'\n", + " '\"alive\": true,'\n", + " '\"age\": 36,'\n", + " '\"traits\": [\"A\",\"F\",\"B\"]'\n", + "'} INTO Characters'\n", + ")\n", + "\n", + "print(cursor)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BzlILU_sEtAp", + "colab_type": "text" + }, + "source": [ + "Note: AQL does not permit multiple INSERT operations that target the same collection in a single query. It is allowed as body of a FOR loop however, inserting multiple documents like we did with above query." + ] + } + ] +} \ No newline at end of file