|
| 1 | += Advanced pipelines |
| 2 | +:keywords: typedb, typeql, tutorial, console |
| 3 | +:pageTitle: |
| 4 | +:summary: |
| 5 | +:page-toclevels: 2 |
| 6 | +:tabs-sync-option: |
| 7 | +:test-typeql: linear |
| 8 | + |
| 9 | +== Overview |
| 10 | + |
| 11 | +This tutorial covers the common patterns of read queries in TypeQL. |
| 12 | + |
| 13 | +== Prerequisites |
| 14 | + |
| 15 | +This tutorial assumes you have access to a running TypeDB instance, as well as a TypeDB Console. |
| 16 | + |
| 17 | +We recommend xref:{page-version}@home::install/ce.adoc[installing TypeDB Community Edition] as it is distributed bundled with Console for easy setup. |
| 18 | + |
| 19 | +== Example schema and data |
| 20 | + |
| 21 | +IMPORTANT: TODO PERMALINKS TO `typedb/typedb-examples` |
| 22 | + |
| 23 | +We are using the https://github.com/typedb/typedb-examples/tree/master/use-cases/bookstore[bookstore example] schema and data throughout this tutorial. |
| 24 | +You can load the example into your TypeDB instance using the following Console command: |
| 25 | + |
| 26 | +[,console] |
| 27 | +---- |
| 28 | +database create-init bookstore http://github.com/typedb/typedb-examples/releases/latest/download/bookstore-schema.tql http://github.com/typedb/typedb-examples/releases/latest/download/bookstore-data.tql |
| 29 | +---- |
| 30 | + |
| 31 | +.Full schema and data queries |
| 32 | +[%collapsible] |
| 33 | +==== |
| 34 | +[,typeql] |
| 35 | +---- |
| 36 | +#!test[schema, commit] |
| 37 | +include::{page-version}@academy::attachment$bookstore-schema.tql[lines=20..] |
| 38 | +---- |
| 39 | +[,typeql] |
| 40 | +---- |
| 41 | +#!test[write, commit] |
| 42 | +include::{page-version}@academy::attachment$bookstore-data.tql[lines=18..] |
| 43 | +---- |
| 44 | +==== |
| 45 | + |
| 46 | +== Conditionals using disjunctions |
| 47 | + |
| 48 | +Let's say we want to create an order for a user, but we want to check the book is in stock first. |
| 49 | +If it isn't, we need to mark the order as invalid. |
| 50 | + |
| 51 | +We can do this by using a xref:{page-version}@typeql-reference::patterns/disjunctions.adoc[disjunction] to check if the book is in stock or not and setting `$status` accordingly. |
| 52 | + |
| 53 | +[,typeql] |
| 54 | +---- |
| 55 | +#!test[write, rollback, count = 1] |
| 56 | +match |
| 57 | + $book isa book, has isbn-13 "9780451162076"; |
| 58 | + { |
| 59 | + $book has stock >= 1; |
| 60 | + let $status = "pending"; |
| 61 | + } or { |
| 62 | + $book has stock < 1; |
| 63 | + let $status = "invalid"; |
| 64 | + }; |
| 65 | +insert |
| 66 | + $order isa order, |
| 67 | + has id "o0067", |
| 68 | + has status == $status; |
| 69 | + $line isa order-line, |
| 70 | + links (order: $order, item: $book), |
| 71 | + has quantity 1; |
| 72 | +---- |
| 73 | + |
| 74 | +== Collect sales statistics using ``reduce``-``groupby`` |
| 75 | + |
| 76 | +We can use a xref:{page-version}@typeql-reference::pipelines/reduce.adoc[reduce] stage to collect sales statistics for each genre within a given year. |
| 77 | + |
| 78 | +The `groupby` keyword allows us to sum the sale quantities grouped by the value of a specific variable, in this case `$genre`. |
| 79 | + |
| 80 | +[,typeql] |
| 81 | +---- |
| 82 | +#!test[write, rollback, count = 8] |
| 83 | +match |
| 84 | + $item isa book, has genre $genre; |
| 85 | + $order-line isa order-line, |
| 86 | + links ($order, $item), |
| 87 | + has quantity $quantity; |
| 88 | + ($order) isa action-execution, |
| 89 | + has timestamp $timestamp; |
| 90 | + $timestamp >= 2022-01-01T00:00; |
| 91 | + $timestamp < 2023-01-01T00:00; |
| 92 | +reduce |
| 93 | + $total-sold = sum($quantity) groupby $genre; |
| 94 | +fetch { |
| 95 | + "genre": $genre, |
| 96 | + "total sold": $total-sold |
| 97 | +}; |
| 98 | +---- |
| 99 | + |
| 100 | +Note that when a book has multiple genres, the number of times it has been sold is included in the results for each genre. |
| 101 | + |
| 102 | +[,] |
| 103 | +---- |
| 104 | +{ |
| 105 | + "genre": "historical fiction", |
| 106 | + "total sold": 5 |
| 107 | +} |
| 108 | +{ |
| 109 | + "total sold": 6, |
| 110 | + "genre": "history" |
| 111 | +} |
| 112 | +{ |
| 113 | + "total sold": 8, |
| 114 | + "genre": "fiction" |
| 115 | +} |
| 116 | +... |
| 117 | +Finished. Total answers: 8 |
| 118 | +---- |
| 119 | + |
| 120 | +== Conditionals using optionals |
| 121 | + |
| 122 | +Imagine we want to update a user's loyalty tier based on their total spending. |
| 123 | +When a user pays for an order, we want to update their total spending and, if their spending has crossed some threshold, we want to increase their loyalty tier as well. |
| 124 | + |
| 125 | +We can use an xref:{page-version}@typeql-reference::patterns/optionals.adoc[optional] pattern to only assign the `$new-loyalty-tier` when necessary. |
| 126 | +Then, we can use the `try` keyword to conditionally set their loyalty tier in the `update` stage. |
| 127 | +The `try` block in the `update` stage will only be executed if the `$new-loyalty-tier` is assigned. |
| 128 | + |
| 129 | +[,typeql] |
| 130 | +---- |
| 131 | +#!test[write, rollback, count = 1] |
| 132 | +match |
| 133 | + $user isa user, has id "u0002"; |
| 134 | + $order isa order, has id "o0004"; |
| 135 | + ($user, $order) isa action-execution; |
| 136 | + ($order, $item) isa order-line, has quantity $quantity; |
| 137 | + $item has price $price; |
| 138 | + let $line-total = $price * $quantity; |
| 139 | +reduce |
| 140 | + $total = sum($line-total) groupby $order, $user; |
| 141 | +match |
| 142 | + $user has total-spending $spending; |
| 143 | + let $new-spending = $spending + $total; |
| 144 | + try { |
| 145 | + $user has loyalty-tier $tier; |
| 146 | + $new-spending > 100 * $tier * $tier; |
| 147 | + $tier < 5; |
| 148 | + let $new-loyalty-tier = $tier + 1; |
| 149 | + }; |
| 150 | +update |
| 151 | + $user has total-spending == $new-spending; |
| 152 | + try { |
| 153 | + $user has loyalty-tier == $new-loyalty-tier; |
| 154 | + }; |
| 155 | +---- |
| 156 | + |
| 157 | +== Further reading |
| 158 | + |
| 159 | +[cols-2] |
| 160 | +-- |
| 161 | +.xref:{page-version}@core-concepts::typeql/index.adoc[] |
| 162 | +[.clickable] |
| 163 | +**** |
| 164 | +TypeQL core concepts |
| 165 | +**** |
| 166 | + |
| 167 | +.xref:{page-version}@core-concepts::typeql/query-clauses.adoc[] |
| 168 | +[.clickable] |
| 169 | +**** |
| 170 | +Learn more about chaining TypeQL clauses into pipelines |
| 171 | +**** |
| 172 | + |
| 173 | +.xref:{page-version}@typeql-reference::index.adoc[] |
| 174 | +[.clickable] |
| 175 | +**** |
| 176 | +TypeQL reference manual |
| 177 | +**** |
| 178 | +-- |
0 commit comments