github.com/dgraph-io/dgraph@v1.2.8/wiki/content/tutorial-4/index.md (about) 1 +++ 2 title = "Get Started with Dgraph - Multi-language strings" 3 +++ 4 5 **Welcome to the fourth tutorial of getting started with Dgraph.** 6 7 In the [previous tutorial]({{< relref "tutorial-3/index.md" >}}), we learned about Datatypes, Indexing, Filtering, and Reverse traversals in Dgraph. 8 9 In this tutorial, we'll learn about using multi-language strings and operations on them using the language tags. 10 11 You can see the accompanying video below. 12 13 {{< youtube _lDE9QXHZC0 >}} 14 15 --- 16 17 ## Strings and languages 18 19 Strings values in Dgraph are of UTF-8 format. 20 Dgraph also supports values for string predicate types in multiple languages. 21 The multi-lingual capability is particularly useful to build features, which requires you to store the same information in multiple languages. 22 23 Let's learn more about them! 24 25 Let's start with building a simple food review Graph. 26 Here's the Graph model. 27 28 {{% load-img "/images/tutorials/4/a-graph-model.jpg" "model" %}} 29 30 The above Graph has three entities: Food, Comment, and Country. 31 32 The nodes in the Graph represent these entities. 33 34 For the rest of the tutorial, let's call the node representing a food item as a `food` node. 35 The node representing a review comment as a `review` node, and the node representing the country of origin as a `country` node. 36 37 Here's the relationship between them: 38 39 - Every food item is connected to its reviews via the `review` edge. 40 - Every food item is connected to its country of origin via the `origin` edge. 41 42 Let's add some reviews for some fantastic dishes! 43 44 How about spicing it up a bit before we do that? 45 46 Let's add the reviews for these dishes in the native language of their country of origin. 47 48 Let's go, amigos! 49 50 ```json 51 { 52 "set": [ 53 { 54 "food_name": "Hamburger", 55 "review": [ 56 { 57 "comment": "Tastes very good" 58 } 59 ], 60 "origin": [ 61 { 62 "country": "United states of America" 63 } 64 ] 65 }, 66 { 67 "food_name": "Carrillada", 68 "review": [ 69 { 70 "comment": "Sabe muy sabroso" 71 } 72 ], 73 "origin": [ 74 { 75 "country": "Spain" 76 } 77 ] 78 }, 79 { 80 "food_name": "Pav Bhaji", 81 "review": [ 82 { 83 "comment": "स्वाद बहुत अच्छा है" 84 } 85 ], 86 "origin": [ 87 { 88 "country": "India" 89 } 90 ] 91 }, 92 { 93 "food_name": "Borscht", 94 "review": [ 95 { 96 "comment": "очень вкусно" 97 } 98 ], 99 "origin": [ 100 { 101 "country": "Russia" 102 } 103 ] 104 }, 105 { 106 "food_name": "mapo tofu", 107 "review": [ 108 { 109 "comment": "真好吃" 110 } 111 ], 112 "origin": [ 113 { 114 "country": "China" 115 } 116 ] 117 } 118 ] 119 } 120 ``` 121 _Note: If this mutation syntax is new to you, refer to the [first tutorial]({{< relref "tutorial-1/index.md">}}) to learn basics of mutation in Dgraph._ 122 123 Here's our Graph! 124 125 {{% load-img "/images/tutorials/4/a-full-graph.png" "full graph" %}} 126 127 Our Graph has: 128 129 - Five blue food nodes. 130 - The green nodes represent the country of origin of these food items. 131 - The reviews of the food items are in pink. 132 133 You can also see that Dgraph has auto-detected the data types of the predicates. 134 You can check that out from the schema tab. 135 136 {{% load-img "/images/tutorials/4/c-schema.png" "full graph" %}} 137 138 _Note: Check out the [previous tutorial]({{< relref "tutorial-3/index.md">}}) to know more about data types in Dgraph._ 139 140 Let's write a query to fetch all the food items, their reviews, and their country of origin. 141 142 Go to the query tab, paste the query, and click Run. 143 144 ```graphql 145 { 146 food_review(func: has(food_name)) { 147 food_name 148 review { 149 comment 150 } 151 origin { 152 country 153 } 154 } 155 } 156 ``` 157 158 _Note: Check the [second tutorial]({{< relref "tutorial-2/index.md">}}) if you want to learn more about traversal queries like the above one_ 159 160 Now, Let's fetch only the food items and their reviews, 161 162 ```graphql 163 { 164 food_review(func: has(food_name)) { 165 food_name 166 review { 167 comment 168 } 169 } 170 } 171 ``` 172 173 As expected, these comments are in different languages. 174 175 {{% load-img "/images/tutorials/4/b-comments.png" "full graph" %}} 176 177 But can we fetch the reviews based on their language? 178 Can we write a query which says: _Hey Dgraph, can you give me only the reviews written in Chinese?_ 179 180 That's possible, but only if you provide additional information about the language of the string data. 181 You can do so by using language tags. 182 While adding the string data using mutations, you can use the language tags to specify the language of the string predicates. 183 184 Let's see the language tags in action! 185 186 I've heard that Sushi is yummy! Let's add a review for `Sushi` in more than one language. 187 We'll be writing the review in three different languages: English, Japanese, and Russian. 188 189 Here's the mutation to do so. 190 191 ```json 192 { 193 "set": [ 194 { 195 "food_name": "Sushi", 196 "review": [ 197 { 198 "comment": "Tastes very good", 199 "comment@jp": "とても美味しい", 200 "comment@ru": "очень вкусно" 201 } 202 ], 203 "origin": [ 204 { 205 "country": "Japan" 206 } 207 ] 208 } 209 ] 210 } 211 ``` 212 213 Let's take a closer look at how we assigned values for the `comment` predicate in different languages. 214 215 We used the language tags (@ru, @jp) as a suffix for the `comment` predicate. 216 217 In the above mutation: 218 219 - We used the `@ru` language tag to add the comment in Russian: `"comment@ru": "очень вкусно"`. 220 221 - We used the `@jp` language tag to add the comment in Japanese: `"comment@jp": "とても美味しい"`. 222 223 - The comment in `English` is untagged: `"comment": "Tastes very good"`. 224 225 In the mutation above, Dgraph creates a new node for the reviews, and stores `comment`, `comment@ru`, and `comment@jp` in different predicates inside the same node. 226 227 _Note: If you're not clear about basic terminology like `predicates`, do read the [first tutorial]({{< relref "tutorial-1/index.md">}})._ 228 229 Let's run the above mutation. 230 231 Go to the mutate tab, paste the mutation, and click Run. 232 233 {{% load-img "/images/tutorials/4/d-lang-error.png" "lang error" %}} 234 235 We got an error! Using the language tag requires you to add the `@lang` directive to the schema. 236 237 Follow the instructions below to add the `@lang` directive to the `comment` predicate. 238 239 - Go to the Schema tab. 240 - Click on the `comment` predicate. 241 - Tick mark the `lang` directive. 242 - Click on the `Update` button. 243 244 {{% load-img "/images/tutorials/4/e-update-lang.png" "lang error" %}} 245 246 Let's re-run the mutation. 247 248 {{% load-img "/images/tutorials/4/f-mutation-success.png" "lang error" %}} 249 250 Success! 251 252 Again, remember that using the above mutation, we have added only one review for Sushi, not three different reviews! 253 254 But, if you want to add three different reviews, here's how you do it. 255 256 Adding the review in the format below creates three nodes, one for each of the comments. 257 But, do it only when you're adding a new review, not to represent the same review in different languages. 258 259 ``` 260 "review": [ 261 { 262 "comment": "Tastes very good" 263 }, 264 { 265 "comment@jp": "とても美味しい" 266 }, 267 { 268 "comment@ru": "очень вкусно" 269 } 270 ] 271 ``` 272 273 Dgraph allows any strings to be used as language tags. 274 But, it is highly recommended only to use the ISO standard code for language tags. 275 276 By following the standard, you eliminate the need to communicate the tags to your team or to document it somewhere. 277 [Click here](https://www.w3schools.com/tags/ref_language_codes.asp) to see the list of ISO standard codes for language tags. 278 279 In our next section, let's make use of the language tags in our queries. 280 281 ## Querying using language tags. 282 283 Let's obtain the review comments only for `Sushi`. 284 285 In the [previous article]({{< relref "tutorial-3/index.md">}}), we learned about using the `eq` operator and the `hash` index to query for string predicate values. 286 287 Using that knowledge, let's first add the `hash` index for the `food_name` predicate. 288 289 {{% load-img "/images/tutorials/4/g-hash.png" "hash index" %}} 290 291 Now, go to the query tab, paste the query in the text area, and click Run. 292 293 ```graphql 294 { 295 food_review(func: eq(food_name,"Sushi")) { 296 food_name 297 review { 298 comment 299 } 300 } 301 } 302 ``` 303 304 {{% load-img "/images/tutorials/4/h-comment.png" "hash index" %}} 305 306 By default, the query only returns the untagged comment. 307 308 But you can use the language tag to query specifically for a review comment in a given language. 309 310 Let's query for a review for `Sushi` in Japanese. 311 ```graphql 312 { 313 food_review(func: eq(food_name,"Sushi")) { 314 food_name 315 review { 316 comment@jp 317 } 318 } 319 } 320 ``` 321 322 {{% load-img "/images/tutorials/4/i-japanese.png" "Japanese" %}} 323 324 Now, let's query for a review for `Sushi` in Russian. 325 326 ```graphql 327 { 328 food_review(func: eq(food_name,"Sushi")) { 329 food_name 330 review { 331 comment@ru 332 } 333 } 334 } 335 ``` 336 337 {{% load-img "/images/tutorials/4/j-russian.png" "Russian" %}} 338 339 You can also fetch all the comments for `Sushi` written in any language. 340 341 ```graphql 342 { 343 food_review(func: eq(food_name,"Sushi")) { 344 food_name 345 review { 346 comment@* 347 } 348 } 349 } 350 ``` 351 352 {{% load-img "/images/tutorials/4/k-star.png" "Russian" %}} 353 354 Here is the table with the syntax for various ways of making use of language tags while querying. 355 356 | Syntax | Result | 357 |------------ |--------| 358 | comment | Look for an untagged string; return nothing if no untagged review exists. | 359 | comment@. | Look for an untagged string, if not found, then return review in any language. But, this returns only a single value. | 360 | comment@jp | Look for comment tagged `@jp`. If not found, the query returns nothing.| 361 | comment@ru | Look for comment tagged `@ru`. If not found, the query returns nothing. | 362 | name@jp:. | Look for comment tagged `@jp` first. If not found, then find the untagged comment. If that's not found too, return anyone comment in other languages. | 363 | name@jp:ru | Look for comment tagged `@jp`, then `@ru`. If neither is found, it returns nothing. | 364 | name@jp:ru:. | Look for comment tagged `@jp`, then `@ru`. If both not found, then find the untagged comment. If that's not found too, return any other comment if it exists. | 365 | name@* | Return all the language tags, including the untagged. | 366 367 If you remember, we had initially added a Russian dish `Borscht` with its review in `Russian`. 368 369 {{% load-img "/images/tutorials/4/l-russian.png" "Russian" %}} 370 371 If you notice, we haven't used the language tag `@ru` for the review written in Russian. 372 373 Hence, if we query for all the reviews written in `Russian`, the review for `Borscht` doesn't make it to the list. 374 375 Only the review for `Sushi,` written in `Russian`, makes it to the list. 376 377 {{% load-img "/images/tutorials/4/m-sushi.png" "Russian" %}} 378 379 So, here's the lesson of the day! 380 381 > If you are representing the same information in different languages, don't forget to add your language tags! 382 383 ## Summary 384 385 In this tutorial, we learned about using multi-language string and operations on them using the language tags. 386 387 The usage of tags is not just restricted to multi-lingual strings. 388 Language tags are just a use case of Dgraph's capability to tag data. 389 390 In the next tutorial, we'll continue our quest into the string types in Dgraph. 391 We'll explore the string type indices in detail. 392 393 Sounds interesting? 394 395 Check out our next tutorial of the getting started series [here]({{< relref "tutorial-5/index.md" >}}). 396 397 ## Need Help 398 399 * Please use [discuss.dgraph.io](https://discuss.dgraph.io) for questions, feature requests and discussions. 400 * Please use [Github Issues](https://github.com/dgraph-io/dgraph/issues) if you encounter bugs or have feature requests. 401 * You can also join our [Slack channel](http://slack.dgraph.io). 402 403 <style> 404 /* blockquote styling */ 405 blockquote { 406 font-size: 1; 407 font-style: italic; 408 margin: 0 3rem 1rem 3rem; 409 text-align: justify; 410 } 411 blockquote p:last-child, blockquote ul:last-child, blockquote ol:last-child { 412 margin-bottom: 0; 413 } 414 blockquote cite { 415 font-size: 15px; 416 font-size: 0.9375rem; 417 line-height: 1.5; 418 font-style: normal; 419 color: #555; 420 } 421 blockquote footer, blockquote small { 422 font-size: 18px; 423 font-size: 1.125rem; 424 display: block; 425 line-height: 1.42857143; 426 } 427 blockquote footer:before, blockquote small:before { 428 content: "\2014 \00A0"; 429 } 430 </style>