{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# What is Semantic Web and RDF?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**RDF (Resource Description Framework)** is one of the three foundational [Semantic Web](https://en.wikipedia.org/wiki/Semantic_Web) technologies, the other two being SPARQL and OWL.\n", "\n", "In particular, RDF is the data model of the Semantic Web. That means that all data in Semantic Web technologies is represented as RDF. If you store Semantic Web data, it's in RDF. If you query Semantic Web data (typically using SPARQL), it's RDF data. If you send Semantic Web data to your friend, it's RDF.\n", "\n", "RDF data model is based upon the idea of making statements about resources (in particular web resources) in the form of *subject–predicate–object* expressions, known as [*triples*](https://en.wikipedia.org/wiki/Semantic_triple). The *subject* denotes the resource, and the *predicate* denotes traits or aspects of the resource, and expresses a relationship between the *subject* and the *object*.\n", "\n", "For example, one way to represent the notion \"The sky has the color blue\" in RDF is as the triple: a **subject** denoting *\"the sky\"*, a **predicate** denoting *\"has the color\"*, and an **object** denoting *\"blue\"*. Therefore, RDF uses subject instead of object(or entity) in contrast to the typical approach of an entity–attribute–value model in object-oriented design: entity (sky), attribute (color), and value (blue).
\n", "(Resource Description Framework, Wikipedia, 2017)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![RDF_example_graph.png](RDF_example_graph.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Find out more:
\n", "- http://fast.wistia.net/embed/iframe/8nm9xf4jip?popover=true
\n", "- https://en.wikipedia.org/wiki/Resource_Description_Framework
\n", "- https://www.cambridgesemantics.com/semantic-university/rdf-101
\n", "- http://www.cambridgesemantics.com/semantic-university/introduction-semantic-web-0" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# RDF<->odML converter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we will explore RDF-odML and odML-RDF conversion in `odml/tools/rdf_converter.py` module.\n", "\n", "If you are new python odML please read the tutorial first:\n", "https://g-node.github.io/python-odml/tutorial.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's create the example odML document." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import os\n", "os.chdir('..')\n", "\n", "import odml\n", "import datetime\n", "\n", "doc = odml.Document(author=\"D. N. Adams\",\n", " date=datetime.date(1979, 10, 12))\n", "\n", "# CREATE AND APPEND THE MAIN SECTIONs\n", "doc.append(odml.Section(name=\"Arthur Philip Dent\",\n", " type=\"crew/person\",\n", " definition=\"Information on Arthur Dent\"))\n", "\n", "# SET NEW PARENT NODE\n", "parent = doc['Arthur Philip Dent']\n", "\n", "\n", "# APPEND PROPERTIES WITH VALUES\n", "parent.append(odml.Property(name=\"Species\",\n", " value=\"Human\",\n", " dtype=odml.DType.string,\n", " definition=\"Species to which subject belongs to\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## RDFWriter class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "RDFWriter class is used for conversion documents from odML to one of the supported RDF formats:
\n", "'xml', 'pretty-xml', 'trix', 'n3', 'turtle', 'ttl', 'ntriples', 'nt', 'nt11', 'trig', 'json-ld'.
\n", "Both one document or list of multiple documents can be passed to `RDFWriter()` constructor.\n", "\n", "It's possible to get the output as a string." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@prefix odml: .\n", "@prefix rdf: .\n", "@prefix rdfs: .\n", "@prefix xml: .\n", "@prefix xsd: .\n", "\n", "odml:Hub odml:hasDocument .\n", "\n", " a odml:Document ;\n", " odml:hasAuthor \"D. N. Adams\" ;\n", " odml:hasDate \"1979-10-12\"^^xsd:date ;\n", " odml:hasSection odml:f3de1e21-f6f5-4eae-8f58-db94ee10f812 .\n", "\n", " a rdf:Bag ;\n", " rdf:li \"Human\" .\n", "\n", "odml:c46a5ee8-811a-4947-8e4b-7f164fbf4c8a a odml:Property ;\n", " odml:hasDefinition \"Species to which subject belongs to\" ;\n", " odml:hasDtype \"string\" ;\n", " odml:hasName \"Species\" ;\n", " odml:hasValue .\n", "\n", "odml:f3de1e21-f6f5-4eae-8f58-db94ee10f812 a odml:Section ;\n", " odml:hasDefinition \"Information on Arthur Dent\" ;\n", " odml:hasName \"Arthur Philip Dent\" ;\n", " odml:hasProperty odml:c46a5ee8-811a-4947-8e4b-7f164fbf4c8a ;\n", " odml:hasType \"crew/person\" .\n", "\n", "\n" ] } ], "source": [ "from odml.tools.rdf_converter import RDFWriter\n", "\n", "print(RDFWriter(doc).get_rdf_str('turtle'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or write the output to the specified file." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@prefix odml: .\n", "@prefix rdf: .\n", "@prefix rdfs: .\n", "@prefix xml: .\n", "@prefix xsd: .\n", "\n", "odml:Hub odml:hasDocument .\n", "\n", " a odml:Document ;\n", " odml:hasAuthor \"D. N. Adams\" ;\n", " odml:hasDate \"1979-10-12\"^^xsd:date ;\n", " odml:hasSection odml:f3de1e21-f6f5-4eae-8f58-db94ee10f812 .\n", "\n", "odml:c46a5ee8-811a-4947-8e4b-7f164fbf4c8a a odml:Property ;\n", " odml:hasDefinition \"Species to which subject belongs to\" ;\n", " odml:hasDtype \"string\" ;\n", " odml:hasName \"Species\" ;\n", " odml:hasValue odml:ddde531a-663a-46f5-b474-edbc73254077 .\n", "\n", "odml:ddde531a-663a-46f5-b474-edbc73254077 a rdf:Bag ;\n", " rdf:li \"Human\" .\n", "\n", "odml:f3de1e21-f6f5-4eae-8f58-db94ee10f812 a odml:Section ;\n", " odml:hasDefinition \"Information on Arthur Dent\" ;\n", " odml:hasName \"Arthur Philip Dent\" ;\n", " odml:hasProperty odml:c46a5ee8-811a-4947-8e4b-7f164fbf4c8a ;\n", " odml:hasType \"crew/person\" .\n", "\n", "\n" ] } ], "source": [ "import tempfile\n", "import os\n", "\n", "# Create temporary file\n", "f = tempfile.NamedTemporaryFile(mode='w', suffix=\".ttl\")\n", "path = f.name\n", "\n", "RDFWriter(doc).write_file(path, \"turtle\")\n", "\n", "with open(path) as ff:\n", " data = ff.read()\n", " print(data)\n", "\n", "f.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## RDFReader class" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "RDFReader class enables RDF to odML conversion.\n", "\n", "There are 2 ways to obtain objects with converted odML documents:\n", "- from **RDF file** ( `RDFReader().from_file(\"/path_to_input_rdf\", \"rdf_format\")` )\n", "- from **RDF string** ( `RDFReader().from_string(\"rdf file as a string\", \"rdf_format\")` )" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[]\n" ] } ], "source": [ "from odml.tools.rdf_converter import RDFReader\n", "\n", "rdf_file = RDFWriter(doc).get_rdf_str('turtle')\n", "odml_doc = RDFReader().from_string(rdf_file, \"turtle\")\n", "\n", "print(odml_doc)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[]\n" ] } ], "source": [ "# Create temporary file\n", "rdf_file = tempfile.NamedTemporaryFile(mode='w', suffix=\".ttl\")\n", "rdf_path = rdf_file.name\n", "RDFWriter(doc).write_file(rdf_path, \"turtle\")\n", "\n", "odml_doc = RDFReader().from_file(rdf_path, \"turtle\")\n", "\n", "print(odml_doc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another option is to write the output to one or multiple files.
\n", "`RDFReader().write_file(\"/input_path\", \"rdf_format\", \"/output_path_to_file\")`" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n", "\n", "
\n", " Arthur Philip Dent\n", " f3de1e21-f6f5-4eae-8f58-db94ee10f812\n", " \n", " Species\n", " c46a5ee8-811a-4947-8e4b-7f164fbf4c8a\n", " [Human]\n", " Species to which subject belongs to\n", " string\n", " \n", " Information on Arthur Dent\n", " crew/person\n", "
\n", " 02e1d29e-937d-4de7-a83e-3e756d954c92\n", " 1979-10-12\n", " D. N. Adams\n", "
\n", "\n" ] } ], "source": [ "# If RDF file contains one odML document, specify output path as file\n", "odml_file = tempfile.NamedTemporaryFile(mode='w', suffix=\".odml\")\n", "odml_path = odml_file.name\n", "\n", "RDFReader().write_file(rdf_path, \"turtle\", odml_path)\n", "\n", "with open(odml_path) as ff:\n", " data = ff.read()\n", " print(data)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "If RDF file contains several odML docs, specify output path as a directory.
\n", "`RDFReader().write_file(\"/input_path\", \"rdf_format\", \"/output_path_to_directory\")`\n", "\n", "Module creates files in specified directory and writes parsed docs to them.\n", "Example of created file: `//doc_.odml`\n", "(`` - id of the document)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Quering the data with rdflib and SPARQL" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total number of triples: 3041\n" ] } ], "source": [ "# please run the first code snipet to change working directory if you have\n", "# [Errno 2] No such file or directory: '/home/rick/g-node/python-odml/doc/doc/example_rdfs/example_data/'\n", "# or insert this line after `import os`: `os.chdir('..')` below\n", "from rdflib import Graph\n", "import os\n", "\n", "graph = Graph()\n", "input_dir = os.path.join(os.getcwd(), 'doc/example_rdfs/example_data/')\n", "for file_name in os.listdir(input_dir):\n", " f = os.path.join(input_dir, file_name)\n", " if os.path.isfile(f):\n", " graph.parse(f, format=\"turtle\")\n", "print('Total number of triples: ', len(graph))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quick video about what is SPARQL: https://www.youtuboe.com/watch?v=FvGndkpa4K0

\n", "Example query using rdflib tool to find each section with type `Recording`, that has property with the name `Recording duration` and prints its value:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Doc: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7, Sec: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd, \n", "Prop: https://g-node.org/projects/odml-rdf#9aeede78-678c-4db8-acb5-fbd6d408b762, Val:13.9\n", "Doc: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a, Sec: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee, \n", "Prop: https://g-node.org/projects/odml-rdf#1636af03-8e97-4ef2-9d7d-6c7db23dcd02, Val:11.88\n", "Doc: https://g-node.org/projects/odml-rdf#24066355-1ee8-4eb5-a715-96bbb6231cd5, Sec: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de, \n", "Prop: https://g-node.org/projects/odml-rdf#0ed215a2-5d20-48eb-b744-bf3b731459fc, Val:0.33\n", "Doc: https://g-node.org/projects/odml-rdf#cc66e78a-3742-490a-9fdb-1c66761d7652, Sec: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956, \n", "Prop: https://g-node.org/projects/odml-rdf#41316903-80f1-45a3-9b06-400a02903531, Val:11.25\n" ] } ], "source": [ "from rdflib import Graph, Namespace, RDF\n", "from rdflib.plugins.sparql import prepareQuery\n", "\n", "q = prepareQuery(\"\"\"SELECT ?d ?s ?p ?value WHERE {\n", " ?d odml:hasSection ?s .\n", " ?s rdf:type odml:Section .\n", " ?s odml:hasType \"Recording\" .\n", " ?s odml:hasProperty ?p .\n", " ?p rdf:type odml:Property .\n", " ?p odml:hasName \"Recording duration\" .\n", " ?p odml:hasValue ?v .\n", " ?v rdf:type rdf:Bag .\n", " ?v rdf:li ?value .}\"\"\", initNs={\"odml\": Namespace(\"https://g-node.org/projects/odml-rdf#\"),\n", " \"rdf\": RDF})\n", "\n", "for row in graph.query(q):\n", " print(\"Doc: {0}, Sec: {1}, \\n\"\n", " \"Prop: {2}, Val:{3}\".format(row.d, row.s, row.p, row.value))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## FuzzyFinder class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**FuzzyFinder** is the tool for querying graph through *fuzzy* queries. The finder executes multiple queries to better match input parameters and returns sets of triples, prioritized from more to less amount of matched parameters.
\n", "\n", "The function `find()` accepts several oprtional parameters.\n", "- `graph`: rdflib graph object\n", "- `q_str`: fuzzy query string, we explore it later\n", "- `q_params`: dict object with parameters of a query\n", "- `mode`: default 'fuzzy' and 'match'\n", "\n", "Each mode works with specific type of fuzzy query (`q_str`).\n", "Let's see on the `match` mode in the example:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasType \"Recording\" .\n", "?s odml:hasProperty ?p .\n", "?p rdf:type odml:Property .\n", "?p odml:hasName \"Date\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#cc66e78a-3742-490a-9fdb-1c66761d7652\n", "Property: https://g-node.org/projects/odml-rdf#f1699eb6-4cab-4dd0-9327-120eab2089ae\n", "Section: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956\n", "Document: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a\n", "Property: https://g-node.org/projects/odml-rdf#138f08f7-23c7-4722-8577-85a6fa633ae1\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "Document: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7\n", "Property: https://g-node.org/projects/odml-rdf#1d6db4ce-87f3-4e9c-b221-e76ba05b2759\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "Document: https://g-node.org/projects/odml-rdf#24066355-1ee8-4eb5-a715-96bbb6231cd5\n", "Property: https://g-node.org/projects/odml-rdf#fadffec7-6b23-454e-bfd1-9d5884802abb\n", "Section: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de\n", "\n", "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasName \"Recording-2013-02-08-ak\" .\n", "?s odml:hasType \"Recording\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "\n", "SELECT * WHERE {\n", "?s odml:hasProperty ?p .\n", "?p rdf:type odml:Property .\n", "?p odml:hasName \"Date\" .\n", "}\n", "Property: https://g-node.org/projects/odml-rdf#1d6db4ce-87f3-4e9c-b221-e76ba05b2759\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "Property: https://g-node.org/projects/odml-rdf#fadffec7-6b23-454e-bfd1-9d5884802abb\n", "Section: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de\n", "Property: https://g-node.org/projects/odml-rdf#f1699eb6-4cab-4dd0-9327-120eab2089ae\n", "Section: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956\n", "Property: https://g-node.org/projects/odml-rdf#138f08f7-23c7-4722-8577-85a6fa633ae1\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "\n", "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasName \"Recording-2013-02-08-ak\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "\n", "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasType \"Recording\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#cc66e78a-3742-490a-9fdb-1c66761d7652\n", "Section: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956\n", "Document: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "Document: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "Document: https://g-node.org/projects/odml-rdf#24066355-1ee8-4eb5-a715-96bbb6231cd5\n", "Section: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de\n", "\n", "\n" ] } ], "source": [ "from odml.tools.fuzzy_finder import FuzzyFinder\n", "\n", "query_string = 'prop(name:Date) section(name:Recording-2013-02-08-ak, type:Recording)'\n", "\n", "f = FuzzyFinder(graph)\n", "print(f.find(mode='match', q_str=query_string))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see from the output, finder builds multiple sparql queries from 'match' queries, executes them and returns some matched results. The first result always represents the most specific query (the biggest combination of input parameters that returned at least one triple).\n", "\n", "The query syntax is pretty straightforward. Just write the name of the entity `property`, `section` or `document` (also possible to use shortened names `prop`, `sec` and `doc`) and add attributes with their values inside the parentheses divided by colon.\n", "\n", "Example from code: `prop(name:Date) section(name:Recording-2013-02-08-ak, type:Recording)`.\n", "Here we search for sections and properties that `property` has attribute `name` and its value is `Date`.\n", "\n", "For building 'match' queries you should need to know exactly for which odML attribute the value(subject) is related. So if you write `prop(name:Date) section(name:Recording, type:Recording-2013-02-08-ak)` the `find()` method would not return any triples with section parameters. Because it's likely that there is no section with type `Recording-2013-02-08-ak`.\n", "\n", "Non-odML entities' attributes here also will be ignored (e.g. only `id, author, date, version, repository, sections` can exist in the `Document` object).\n", "In the example `section(not-odml-name:Recording-2013-02-08-ak, record:Recording)` the find method return nothing." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "from odml.tools.fuzzy_finder import FuzzyFinder\n", "\n", "query_string = 'section(not-odml-name:Recording-2013-02-08-ak, record:Recording)'\n", "\n", "f = FuzzyFinder(graph)\n", "print(f.find(mode='match', q_str=query_string))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is often inconvinient if you do not know exactly what the information is related to in the graph. For situations like this *'fuzzy'* mode comes into play. It is also set by default.\n", "\n", "The output logic is similair to the previous mode, but there you can provide more broad information, the finder will match the parameters and create meaningful queries based on the input.\n", "\n", "The query string consists of two parts: *FIND* and *HAVING*.\n", "\n", "In the *FIND* part a user specifies the set of odML objects and its attributes. \n", "e.g. `FIND prop(name) section(name, type)`\n", "\n", "In the *HAVING* part a user specifies set of search values which could relate to the attributes in *FIND* part.\n", "e.g `HAVING Recording, Recording-2012-04-04-ab, Date`\n", "\n", "Finally, the complete query will look like this:\n", "`FIND sec(name, type) prop(name) HAVING Recording, Recording-2012-04-04-ab, Date`\n", "\n", "As you can see in the example you should not really know to which attribute search values in *HAVING* part relates to, the finder can do it for you." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasType \"Recording\" .\n", "?s odml:hasProperty ?p .\n", "?p rdf:type odml:Property .\n", "?p odml:hasName \"Date\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#cc66e78a-3742-490a-9fdb-1c66761d7652\n", "Property: https://g-node.org/projects/odml-rdf#f1699eb6-4cab-4dd0-9327-120eab2089ae\n", "Section: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956\n", "Document: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a\n", "Property: https://g-node.org/projects/odml-rdf#138f08f7-23c7-4722-8577-85a6fa633ae1\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "Document: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7\n", "Property: https://g-node.org/projects/odml-rdf#1d6db4ce-87f3-4e9c-b221-e76ba05b2759\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "Document: https://g-node.org/projects/odml-rdf#24066355-1ee8-4eb5-a715-96bbb6231cd5\n", "Property: https://g-node.org/projects/odml-rdf#fadffec7-6b23-454e-bfd1-9d5884802abb\n", "Section: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de\n", "\n", "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasName \"Recording\" .\n", "?s odml:hasType \"Recording\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "\n", "SELECT * WHERE {\n", "?s odml:hasProperty ?p .\n", "?p rdf:type odml:Property .\n", "?p odml:hasName \"Date\" .\n", "}\n", "Property: https://g-node.org/projects/odml-rdf#1d6db4ce-87f3-4e9c-b221-e76ba05b2759\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "Property: https://g-node.org/projects/odml-rdf#fadffec7-6b23-454e-bfd1-9d5884802abb\n", "Section: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de\n", "Property: https://g-node.org/projects/odml-rdf#f1699eb6-4cab-4dd0-9327-120eab2089ae\n", "Section: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956\n", "Property: https://g-node.org/projects/odml-rdf#138f08f7-23c7-4722-8577-85a6fa633ae1\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "\n", "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasName \"Recording\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "\n", "SELECT * WHERE {\n", "?d odml:hasSection ?s .\n", "?s rdf:type odml:Section .\n", "?s odml:hasType \"Recording\" .\n", "}\n", "Document: https://g-node.org/projects/odml-rdf#cc66e78a-3742-490a-9fdb-1c66761d7652\n", "Section: https://g-node.org/projects/odml-rdf#5365f7e5-603c-4154-a5ea-33bb1a07a956\n", "Document: https://g-node.org/projects/odml-rdf#537c6cc8-7dfe-4d53-a111-24b3ce0f3c1a\n", "Section: https://g-node.org/projects/odml-rdf#346773f2-abee-4892-b052-840ddcff35ee\n", "Document: https://g-node.org/projects/odml-rdf#cd24b60f-1d5e-4040-9881-5e5a597baef7\n", "Section: https://g-node.org/projects/odml-rdf#782bd29d-e4b0-4c14-a417-1772a4851ffd\n", "Document: https://g-node.org/projects/odml-rdf#24066355-1ee8-4eb5-a715-96bbb6231cd5\n", "Section: https://g-node.org/projects/odml-rdf#bbd44815-5016-49e0-9f4b-5b83778d00de\n", "\n", "\n" ] } ], "source": [ "from odml.tools.fuzzy_finder import FuzzyFinder\n", "\n", "query_string = 'FIND sec(name, type) prop(name) HAVING Recording, Recording-2012-04-04-ab, Date, Some_value'\n", "\n", "f = FuzzyFinder(graph)\n", "print(f.find(mode='fuzzy', q_str=query_string))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3.0 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }