|
| 1 | +# Lesson 7 - Logical query using triple and WOQL |
| 2 | + |
| 3 | +In this lesson we are exploring to a more advance territories. We will make some logical query with WOQL query. In may cases we only need to make document queries with the document interface that we covered in lesson 1 to 5. But in rare occasions, logical queries maybe the more straight forward and easy way to find information form the data we stored in our database |
| 4 | + |
| 5 | +## Triples - Subject, Predicate and Object |
| 6 | + |
| 7 | +In TerminusDB as store things as triples, each of them is consists of 'Subject', 'Predicate' and 'Object'. We can inspect all the the triples in a graph (in the following example, the instance graph) by using `star()` in `WOQLQuery`: |
| 8 | + |
| 9 | +``` |
| 10 | +import pprint as pp |
| 11 | +
|
| 12 | +from terminusdb_client import WOQLClient |
| 13 | +from terminusdb_client import WOQLQuery as wq |
| 14 | +
|
| 15 | +client = WOQLClient("http://127.0.0.1:6363/") |
| 16 | +client.connect(db="getting_started") |
| 17 | +
|
| 18 | +pp.pprint(wq().star().execute(client)) |
| 19 | +``` |
| 20 | + |
| 21 | +By inspecting the output of the above code, we see all the triples within our instance graph. |
| 22 | + |
| 23 | +With a bit of understand of how triples are related to each other, we can link up a few triples, leaving some "variables" which we wants to find the answer with, we can make WOQL queries which harness the power of logical programming in Prolog. We will explain all of it with examples. |
| 24 | + |
| 25 | +## WOQLQuery - Making logical queries with triples |
| 26 | + |
| 27 | +Let's imagine you are working with Awesome Startup in the example. You would like to find our the contact number of Darci, our creative writer to discuss about the next article publication. Here is how it is done: |
| 28 | + |
| 29 | +``` |
| 30 | +from terminusdb_client import WOQLClient |
| 31 | +from terminusdb_client import WOQLQuery as wq |
| 32 | +
|
| 33 | +client = WOQLClient("http://127.0.0.1:6363/") |
| 34 | +client.connect(db="getting_started") |
| 35 | +
|
| 36 | +darci = wq().string("Darci Prosser") |
| 37 | +
|
| 38 | +query = wq().triple("v:person", "@schema:name", darci) + wq().triple("v:person", "@schema:contact_number", "v:phone_num") |
| 39 | +
|
| 40 | +result = query.execute(client) |
| 41 | +
|
| 42 | +if result["bindings"]: |
| 43 | + print("Darci's contact number:") |
| 44 | + print(result["bindings"][0]["phone_num"]["@value"]) |
| 45 | +else: |
| 46 | + print("Cannot find result.") |
| 47 | +
|
| 48 | +``` |
| 49 | + |
| 50 | +A few things to note here, first we have to create a WOQLQuery object with the string `"Darci Prosser"` as it needed to be started explicitly as a string in the database, not a string that we used to construct the query like `"v:person"` or `"@schema:name"`. |
| 51 | + |
| 52 | +Second, the prefix before the `:` is telling TerminusDB how to treat the strings in the query. For example, a `v:` denote a variable so `v:person` is a variable that we don't know and would like to find what it is in the query. On the other hand, `@schema:` denote that it is a property that is defined in the schema, so `@schema:name` says that `name` is the property that we stated for the `Employee` documents in the schema. |
| 53 | + |
| 54 | +Third, we can linked up the triples that we created with [`wq().triple`](https://terminusdb.github.io/terminusdb-client-python/woqlQuery.html#terminusdb_client.WOQLQuery.triple) with either [`wq().woql_and`](https://terminusdb.github.io/terminusdb-client-python/woqlQuery.html#terminusdb_client.WOQLQuery.woql_and) or a simple `+` like we did above. |
| 55 | + |
| 56 | +So the query above can be interpreted as: |
| 57 | + |
| 58 | +`There is a person who's name is "Darci Prosser" and I would like to know that person's contact number.` |
| 59 | + |
| 60 | +As you see, making WOQL queries is quite logical, just need to think what questions you are asking and how to link up all the questions and informations with triple. With some practice you can get use to it. Let's try another one in the next example. |
| 61 | + |
| 62 | +Let's say you have called Darci and unfortunately she is on holiday and you cannot wait for her to be back to talk about it. You decided to contact her manager instead. However, you do not know who her manager is and don't know the manager's contact number either. But fear not! With WOQL query it is not more complicated that making our previous query. |
| 63 | + |
| 64 | +``` |
| 65 | +query = wq().triple("v:person", "@schema:name", darci) + wq().triple("v:person", "@schema:manager", "v:manager") + wq().triple("v:manager", "@schema:contact_number", "v:phone_num") + wq().triple("v:manager", "@schema:name", "v:manager_name") |
| 66 | +
|
| 67 | +result = query.execute(client) |
| 68 | +
|
| 69 | +if result["bindings"]: |
| 70 | + print("Manager's name:") |
| 71 | + print(result["bindings"][0]["manager_name"]["@value"]) |
| 72 | + print("Manager's contact number:") |
| 73 | + print(result["bindings"][0]["phone_num"]["@value"]) |
| 74 | +else: |
| 75 | + print("Cannot find result.") |
| 76 | +``` |
| 77 | + |
| 78 | +This time, instead of asking for Darci's contact number, you ask `who is the manager` and set the manager as a variable `v:manager`. Then with `v:manager` you can find out the `name` and `contact_number` of the manager. |
| 79 | + |
| 80 | +As you can see, when the question get more complicated, more triple is added to link up extra information. But the structure of the query is the same and it is much efficient and easier than joining tables many times in SQL queries to get the same answer. |
| 81 | + |
| 82 | +Feel free to practice and play with the WOQL query. The code we showed in this lesson can be found in the file [woql_query.py](woql_query.py) |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +[Check out other tutorials](README.md) |
0 commit comments