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>