Last active
March 5, 2018 03:38
-
-
Save williballenthin/9e5891c967004eee8bdf256cbd4f9fcc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [ | |
"import pprint\n", | |
"import tabulate\n", | |
"\n", | |
"import synapse.cortex\n", | |
"import synapse.daemon\n", | |
"import synapse.telepath\n", | |
"import synapse.lib.service\n", | |
"import synapse.swarm.runtime" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": true, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [ | |
"ID = 0\n", | |
"PROPS = 1" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## setup" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [ | |
"core = synapse.cortex.openurl('ram://')\n", | |
"\n", | |
"core.formTufoByProp('person', 'alex', age=10, haircolor='brown', height=60, petname='zuzu')\n", | |
"core.formTufoByProp('person', 'brian', age=10, haircolor='red', height=62, petname='xinxin')\n", | |
"core.formTufoByProp('person', 'carl', age=12, haircolor='black', height=62)\n", | |
"\n", | |
"core.formTufoByProp('pet', 'zuzu', animal='cat')\n", | |
"core.formTufoByProp('pet', 'yiyi', animal='parrot')\n", | |
"core.formTufoByProp('pet', 'xinxin', animal='dog')\n", | |
"\n", | |
"None" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# a svcbus is an eventbus that multiple services can share and use to communicate with one another.\n", | |
"svcbus = synapse.lib.service.SvcBus()\n", | |
"\n", | |
"# a daemon listens on an address and can respond to requests.\n", | |
"# this might spawn a background thread to handle requests? TODO.\n", | |
"dmon = synapse.daemon.Daemon()\n", | |
"# the link has details about the listening daemon.\n", | |
"# things like the ip, port, username, url, etc.\n", | |
"link = dmon.listen('tcp://127.0.0.1:0')\n", | |
"port = link[1].get('port')\n", | |
"\n", | |
"# share the event bus that services can use over the daemon via the telepath protocol.\n", | |
"# clients that connect to the daemon can then attach services, and other clients can interact with those services.\n", | |
"# the telepath protocol is ... TODO\n", | |
"dmon.share('thebus', svcbus)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"('tcp',\n", | |
" {'host': '127.0.0.1',\n", | |
" 'passwd': None,\n", | |
" 'path': '',\n", | |
" 'port': 34627,\n", | |
" 'url': 'tcp://127.0.0.1:0',\n", | |
" 'user': None})\n" | |
] | |
} | |
], | |
"source": [ | |
"pprint.pprint(link)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'5debf1fea349ec483e993bcfa1eb5398'" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# connect to the remote svcbus via telepath.\n", | |
"# this lets us call methods registered on the remote svcbus as if they were local.\n", | |
"rsvcbus = synapse.telepath.openurl('tcp://127.0.0.1/thebus', port=port)\n", | |
"\n", | |
"# attach a cortex to the service bus.\n", | |
"# now any client of the remote service bus can call methods on the cortex.\n", | |
"synapse.lib.service.runSynSvc('thecortex', core, rsvcbus)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"collapsed": true, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# first argument: telepath'd service bus instance\n", | |
"# this cannot be the core directly. nor a local SvcBus.\n", | |
"swarm = synapse.swarm.runtime.Runtime(rsvcbus)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## querying" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"`swarm.ask` returns dictionaries with the following keys:\n", | |
"\n", | |
" - `data`: contains the matches.\n", | |
" - `limits`: from the query.\n", | |
" - `options`: from the query.\n", | |
" \n", | |
"`data` is a list of tufos. each has a pseudo-prop named `.from` that... indicates which cortex returned the result? TODO." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"we can build an initial set of tufos using the swarm query features. they are:\n", | |
" - all tufos with a given form\n", | |
" - the tufo with the given key\n", | |
" - all tufos with a given prop value (exact match, or numeric comparison match)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"collapsed": true, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def format_results(results):\n", | |
" '''\n", | |
" format and print the results from a swarm query.\n", | |
" makes a nice table.\n", | |
" columns are discovered props.\n", | |
" rows are each tufo in the swarm results.\n", | |
" '''\n", | |
" rows = []\n", | |
" headers = set([])\n", | |
" \n", | |
" for result in results['data']:\n", | |
" for header in result[PROPS].keys():\n", | |
" if header.startswith('.'):\n", | |
" # ignore pseudo-props\n", | |
" continue\n", | |
" if header == 'tufo:form':\n", | |
" # right now, we assume the form is obvious from the query\n", | |
" continue\n", | |
" headers.add(header)\n", | |
" \n", | |
" # sorted by prop name length ensures that the key is first (in a well-formed tufo).\n", | |
" #headers = sorted(list(headers), key=len)\n", | |
" headers = sorted(list(headers))\n", | |
" \n", | |
" for result in results['data']:\n", | |
" row = []\n", | |
" for header in headers:\n", | |
" row.append(result[PROPS].get(header))\n", | |
" rows.append(row)\n", | |
"\n", | |
" print(tabulate.tabulate(rows, headers=headers))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### query by form" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"carl 12 black 62\n", | |
"brian 10 red 62 xinxin\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# get all the person tufos\n", | |
"format_results(swarm.ask('person'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### query by key" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"fetch the tufo with the given key." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"result = swarm.ask('person=\"alex\"')\n", | |
"format_results(result)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"('216a6ce4def57879caabfe2277e34c6f',\n", | |
" {'person': 'alex',\n", | |
" 'person:age': 10,\n", | |
" 'person:haircolor': 'brown',\n", | |
" 'person:height': 60,\n", | |
" 'person:petname': 'zuzu',\n", | |
" 'tufo:form': 'person'})" | |
] | |
}, | |
"execution_count": 12, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"first_match = result['data'][0]\n", | |
"core.getTufoByIden(first_match[ID])" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"we can include multiple specifiers to create a collection." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"format_results(swarm.ask('person=\"alex\" person=\"brian\"'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# by default, tufos are de-duped upon return\n", | |
"format_results(swarm.ask('person=\"alex\" person=\"alex\"'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### query by numeric comparison" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n", | |
"carl 12 black 62\n" | |
] | |
} | |
], | |
"source": [ | |
"# greater than\n", | |
"format_results(swarm.ask('person:height>61'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n", | |
"carl 12 black 62\n" | |
] | |
} | |
], | |
"source": [ | |
"# greater than or equals\n", | |
"format_results(swarm.ask('person:height>=62'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# less than, etc.\n", | |
"format_results(swarm.ask('person:height<61'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## filtering" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"with filtering, we can restrict the tufos returned by a query. we can use either include (`+`) or exclude (`-`) modes." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### filter by prop" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# get all persons, \n", | |
"# then only include the persons with age 10.\n", | |
"format_results(swarm.ask('person +person:age=10'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height\n", | |
"-------- ------------ ------------------ ---------------\n", | |
"carl 12 black 62\n" | |
] | |
} | |
], | |
"source": [ | |
"# get all persons, \n", | |
"# then *exclude* the persons with age 10.\n", | |
"format_results(swarm.ask('person -person:age=10'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"these seem like contrived examples, because you could simply ask `person:age=10` instead. but filtering is nice because it operates over any collection. so lets filter something more complex." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# get all persons with the same age as alex (who is 10), and from that set,\n", | |
"# get all persons with the same height as anyone in the set (60 or 62),\n", | |
"# then filter people with brown haircolor.\n", | |
"format_results(swarm.ask('person=\"alex\" ^person:age ^person:height +person:haircolor=\"brown\"'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### filter by regex" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"you cannot make a swarm query using regexes. you must have an existing collection and then filter them." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true, | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"carl 12 black 62\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# start with all persons, \n", | |
"# and then only include the persons with a haircolor that starts with 'b'.\n", | |
"format_results(swarm.ask('person +person:haircolor~=\"^b\"'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# start with all persons, \n", | |
"# and then *exclude* the persons with a haircolor that starts with 'b'\n", | |
"format_results(swarm.ask('person -person:haircolor~=\"^b\"'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### filter combinations" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"#### AND (`&`)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# fetch all people\n", | |
"# then only include those with:\n", | |
"# age 10, AND\n", | |
"# red hair\n", | |
"format_results(swarm.ask('person +person:age=10 & person:haircolor=\"red\"'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"and we can continue to chain these together. `&` is not a binary operator. i think its left-associative, and we can keep chaining combinations." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# fetch all people\n", | |
"# then only include those with:\n", | |
"# age 10, AND\n", | |
"# red hair, AND\n", | |
"# height 62\n", | |
"format_results(swarm.ask('person +person:age=10 & person:haircolor=\"red\" & person:height=62'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"note that logically, chaining `&` combinations and `+` filters has the same effect. using `&` combinations *may* have better performance since fewer intermediate lists may be allocated by the query engine (but this is implementation-specific)." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# fetch all people\n", | |
"# only include those of age 10, then\n", | |
"# only include those with haircolor red, then\n", | |
"# only include height 62\n", | |
"format_results(swarm.ask('person +person:age=10 +person:haircolor=\"red\" +person:height=62'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"#### OR (`|`)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# fetch all people\n", | |
"# only include those with:\n", | |
"# age 10, OR\n", | |
"# haircolor red\n", | |
"format_results(swarm.ask('person +person:age=10 | person:haircolor=\"red\"'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# fetch all people\n", | |
"# only include those with:\n", | |
"# age 10, OR\n", | |
"# haircolor red\n", | |
"# then, only include those with height 62\n", | |
"format_results(swarm.ask('person +person:age=10 | person:haircolor=\"red\" +person:height=62'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# fetch all people\n", | |
"# only include those with:\n", | |
"# AND\n", | |
"# +-> only include those with:\n", | |
"# | age 10, OR\n", | |
"# | haircolor red\n", | |
"# +-> height 62\n", | |
"format_results(swarm.ask('person +person:age=10 | person:haircolor=\"red\" & person:height=62'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## pivot" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"with a result, fetch all tufos that have the same value for a given prop.\n", | |
"\n", | |
"note: the input set can be singular, or a collection." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# ask for all persons with the same age as alex (who is 10)\n", | |
"format_results(swarm.ask('person=\"alex\" ^person:age'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n", | |
"carl 12 black 62\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# get all persons with the same age as alex (who is 10), and from that set,\n", | |
"# get all persons with the same height as anyone in the set (60 or 62).\n", | |
"format_results(swarm.ask('person=\"alex\" ^person:age ^person:height'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## passing options" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"pass options to... the query runtime? TODO.\n", | |
"\n", | |
"i guess these can be used by specific indices to help the query.\n", | |
"\n", | |
"TODO: not sure what options are actually supported. or how they're defined." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 31, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'data': [],\n", | |
" 'limits': {'lift': None, 'time': None, 'touch': None},\n", | |
" 'oplog': [{'add': 0, 'mnem': 'opts', 'sub': 0, 'took': 0}],\n", | |
" 'options': {'option_1': 1, 'uniq': 1}}" | |
] | |
}, | |
"execution_count": 31, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# provide a flag option\n", | |
"swarm.ask('%option_1')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 32, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'data': [],\n", | |
" 'limits': {'lift': None, 'time': None, 'touch': None},\n", | |
" 'oplog': [{'add': 0, 'mnem': 'opts', 'sub': 0, 'took': 0}],\n", | |
" 'options': {'option_2': 'lowercase', 'uniq': 1}}" | |
] | |
}, | |
"execution_count": 32, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# provide a kwarg option\n", | |
"swarm.ask('%option_2=\"lowercase\"')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### option: uniq" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 33, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# by default, tufos are de-duped upon return\n", | |
"# but we can disable this behavior with the `uniq` option\n", | |
"format_results(swarm.ask('%uniq=0 person=\"alex\" person=\"alex\"'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## save/load" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### clear" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"clear the current result set" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 34, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"format_results(swarm.ask('person=\"alex\" clear()'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### save" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"save a result set by name, which can be restored later." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 35, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"format_results(swarm.ask('person=\"alex\" save(\"somename\")'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"note that saving a result doesn't implicitly clear it, so you'll have to do this yourself if you want to go chasing some other data." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 36, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"format_results(swarm.ask('person=\"alex\" save(\"somename\") clear()'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"### load" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"once some data has been saved, it can be restored." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# find the person named alex,\n", | |
"# save him,\n", | |
"# clear the result set,\n", | |
"# and then restore him.\n", | |
"format_results(swarm.ask('person=\"alex\" save(\"somename\") clear() load(\"somename\")'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"if there are already some results in the set, merge in the loaded data." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 38, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n", | |
"alex 10 brown 60 zuzu\n" | |
] | |
} | |
], | |
"source": [ | |
"# find the person named alex,\n", | |
"# save him,\n", | |
"# clear the result set,\n", | |
"# find the person named brian,\n", | |
"# and merge the results that had alex.\n", | |
"format_results(swarm.ask('person=\"alex\" save(\"somename\") clear() person=\"brian\" load(\"somename\")'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## has" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"not sure how this works. test is broken. see [here](https://github.com/vivisect/synapse/issues/55).\n", | |
"\n", | |
"i presume that it should only return rows that have the given prop name." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"format_results(swarm.ask('person=\"alex\" ^person:age ^person:height has(\"person:petname\")'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"## join" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"join traverses tufos by connecting props of different names but the same value." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 41, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname pet pet:animal\n", | |
"-------- ------------ ------------------ --------------- ---------------- ------ ------------\n", | |
"carl 12 black 62\n", | |
"brian 10 red 62 xinxin\n", | |
"alex 10 brown 60 zuzu\n", | |
" yiyi parrot\n", | |
" zuzu cat\n", | |
" xinxin dog\n" | |
] | |
} | |
], | |
"source": [ | |
"# get all persons,\n", | |
"# and merge in all pets whose key exists as a person's petname\n", | |
"format_results(swarm.ask('person join(\"pet\", \"person:petname\")'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"get all the tufos \"pointed to by these tufos\".\n", | |
"\n", | |
"`(current)->(?)`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 42, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"pet pet:animal\n", | |
"------ ------------\n", | |
"yiyi parrot\n", | |
"zuzu cat\n", | |
"xinxin dog\n" | |
] | |
} | |
], | |
"source": [ | |
"# \"get all pets owned by persons\"\n", | |
"#\n", | |
"# get all persons,\n", | |
"# merge in all pets whose key exists as a person's petname\n", | |
"# and keep only the pets\n", | |
"format_results(swarm.ask('person join(\"pet\", \"person:petname\") +pet'))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"deletable": true, | |
"editable": true | |
}, | |
"source": [ | |
"get the tufos that \"point at this tufo\".\n", | |
"\n", | |
"`(current)<-(?)`\n", | |
"\n", | |
"note this requires you to know the other props that might point here." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 43, | |
"metadata": { | |
"collapsed": false, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"person person:age person:haircolor person:height person:petname\n", | |
"-------- ------------ ------------------ --------------- ----------------\n", | |
"brian 10 red 62 xinxin\n" | |
] | |
} | |
], | |
"source": [ | |
"# \"get the person that owns this pet\"\n", | |
"#\n", | |
"# get the pet \"xinxin\",\n", | |
"# fetch the persons with petname matching this pet's key (\"xinxin\"),\n", | |
"# and keep only the persons\n", | |
"format_results(swarm.ask('pet=\"xinxin\" join(\"person:petname\", \"pet\") +person'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true, | |
"deletable": true, | |
"editable": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.5.2" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment