|
| 1 | +--- |
| 2 | +title: "WOQL Cookbook: Finding and matching datatypes" |
| 3 | +nextjs: |
| 4 | + metadata: |
| 5 | + title: "WOQL Cookbook: Finding and matching datatypes" |
| 6 | + description: Examples of WOQL query patterns with datatypes using the WOQL datalog type_of() in three different ways |
| 7 | + keywords: woql, query, datalog, cookbook, declarative logic |
| 8 | + openGraph: |
| 9 | + images: https://assets.terminusdb.com/docs/technical-documentation-terminuscms-og.png |
| 10 | + alternates: |
| 11 | + canonical: https://terminusdb.org/docs/cookbook-woql-query-patterns/ |
| 12 | +media: [] |
| 13 | +--- |
| 14 | + |
| 15 | +This page is intended to show how to accomplish goals with WOQL. Before really "getting" WOQL, it feels counter-intuitive as solutions are generated using patterns. |
| 16 | + |
| 17 | +Logicians and people hanving used prolog, datalog and similar declarative languages will find it easier to understand the core concepts of unification and generator patterns and we hope the examples on this page will help show common solutions. |
| 18 | + |
| 19 | +## How the examples on this page work |
| 20 | + |
| 21 | +Most of the work in TerminusDB happens with data that is stored in the instance graph. WOQL is not limited to processing stored graph information, it is also possible to process supplied CSV files and build patterns using the `member()` predicate. |
| 22 | + |
| 23 | +The examples on the first section of the page are kept as simple as possible, to enable running them without schema or instance data. The second section will require a schema and instance data with some instructions on how to set it up. |
| 24 | + |
| 25 | +You are expected to have instance data to query and a basic undertanding of querying triples of the graph and processing documents with knowledge of datatypes, sets, lists, arrays etc. |
| 26 | + |
| 27 | +## Variables |
| 28 | + |
| 29 | +Variable unification is core to the WOQL engine. Read up on [unification](/docs/unification-of-variables-in-datalog/) if you are unsure, and play with the examples on this page to learn. |
| 30 | + |
| 31 | +## Understanding value types |
| 32 | + |
| 33 | +All values that are processed in TerminusDB are of a certain type. Sometimes it's important to either match a type, understand what datatype a value has, or to match elements in a variable to a datatype. |
| 34 | + |
| 35 | +Thanks to pattern matching this can be done with the very same predicate, used in multiple ways. |
| 36 | + |
| 37 | +### Code: Which type a value has |
| 38 | + |
| 39 | +The `type_of` predicate can be used to bind a variable to the type of a value, `v:datatype` in this example. This is useful when you want to match values with specific types, such as specific classes of integers, or match all kinds of decimal numbers, floats and doubles. |
| 40 | + |
| 41 | +```woql |
| 42 | +and( |
| 43 | + member("v:list", [literal("MyString", "xsd:string"), literal(1, "xsd:integer")]), |
| 44 | + type_of("v:list", "v:datatype") |
| 45 | +) |
| 46 | +``` |
| 47 | + |
| 48 | +The above yields: |
| 49 | + |
| 50 | +{% table %} |
| 51 | + |
| 52 | +- list |
| 53 | +- datatype |
| 54 | + |
| 55 | +--- |
| 56 | + |
| 57 | +- MyString |
| 58 | +- xsd:string |
| 59 | + |
| 60 | +--- |
| 61 | + |
| 62 | +- 1 |
| 63 | +- xsd:integer |
| 64 | + |
| 65 | +{% /table %} |
| 66 | + |
| 67 | +### Code: Which value is a string? |
| 68 | + |
| 69 | +Here we use `type_of()` in a different way, where we instead bind the type parameter to a specific type, `xsd:string`, to constrain the allowed values in `v:list` for the solutions to return. |
| 70 | + |
| 71 | +```woql |
| 72 | +and( |
| 73 | + member("v:list", [ |
| 74 | + literal("MyString1", "xsd:string"), |
| 75 | + literal(1, "xsd:integer"), |
| 76 | + literal("MyString2", "xsd:string") |
| 77 | + ]), |
| 78 | + type_of("v:list", "xsd:string") |
| 79 | +) |
| 80 | +``` |
| 81 | + |
| 82 | +The above yields: |
| 83 | + |
| 84 | +{% table %} |
| 85 | + |
| 86 | +- list |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +- MyString1 |
| 91 | + |
| 92 | +--- |
| 93 | + |
| 94 | +- MyString2 |
| 95 | + |
| 96 | +{% /table %} |
| 97 | + |
| 98 | +### Code: Is a specific value a string? |
| 99 | + |
| 100 | +In the last example, which is a bit contrived, we check if the literal string is a string, and bind a variable to a value if the comparison is true. |
| 101 | + |
| 102 | +What is important in this example is that all statements of the `and()` predicate must resolve to true for it to be a solution. Thus, we know that there must be equality for a solution to be returned. |
| 103 | + |
| 104 | +To make this a bit more interesting, we use optionality to offer two variables that are both optional so that only one solution is returned, where one comparison is true, and the other isn't. |
| 105 | + |
| 106 | +In order to satisfy the `and()` predicate, the solution result of the literal check needs to be inverted using the `not()` operator, and then the `eq()` operator sets the variable `v:is_integer` to be `false` as the result of the comparison is not true. |
| 107 | + |
| 108 | +```woql |
| 109 | +and( |
| 110 | + opt().and( |
| 111 | + type_of(literal("", "xsd:string"), "xsd:string"), |
| 112 | + eq("v:is_string", true) |
| 113 | + ), |
| 114 | + opt().and( |
| 115 | + not().type_of(literal("", "xsd:string"), "xsd:integer"), |
| 116 | + eq("v:is_integer", false) |
| 117 | + ) |
| 118 | +) |
| 119 | +``` |
| 120 | + |
| 121 | +The above yields: |
| 122 | + |
| 123 | +{% table %} |
| 124 | + |
| 125 | +- is_string |
| 126 | +- is_integer |
| 127 | + |
| 128 | +--- |
| 129 | + |
| 130 | +- true |
| 131 | +- false |
| 132 | + |
| 133 | +{% /table %} |
| 134 | + |
| 135 | +## Conclusion |
| 136 | + |
| 137 | +WOQL predicates can be used in many ways. Through clever use of them, problems that are hard to solve in other ways, often get elegant solutions using WOQL, thanks to the powerful pattern matching capabilities of WOQL and the flexible use of variables. |
| 138 | + |
| 139 | +Traditional database query languages like SQL are limited to the data and the columns that are available, which makes it hard to write solutions with declarative logic. |
| 140 | + |
| 141 | +The flexibility to use the logical predicates in multiple ways makes it practical to write solutions using declarative logic. |
0 commit comments