暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【译】Dgraph入门: UID操作、节点更新以及遍历(系列二)

背井 2021-03-03
2135

这是Dgraph系列文章的第二篇。在上一篇中,我们学习了Dgraph的基本知识,包括运行Dgraph、添加新的nodes和predicates,以及查询它们。


在本篇中,我们将打造上图所示的Graph,并利用 UID 来学习更多的操作。确切地说,我们将学习:

  • 基于UIDs查询、更新nodes或删除predicates

  • 为已有的nodes添加edge

  • 为已有的node添加predicate

  • 遍历这个Graph


首先,让我们创建该Graph。


打开Ratel的 mutate tab 面,复制并运行以下内容:


    {
    "set":[
    {
    "name": "Michael",
    "age": 40,
    "follows": {
    "name": "Pawan",
    "age": 28,
    "follows":{
    "name": "Leyla",
    "age": 31
    }
    }
    }
    ]
    }


    基于UIDs的查询


    我们可以基于nodes的UID来查询这些nodes。内置的 uid 函数接收一组 UIDs 作为变长参数,这样我们既可以传入一个 UID(如 uid(0x1)) 也可以按需传入多个(如 uid(0x1,0x2))


    uid 函数返回的UID和我们传入的一样,不管UID在数据库中是否存在。但是只有当UID以及它们所关联的predicates存在时,返回值中才会出现所要求的predicates。


    uid 函数实战。


    首先,复制 Michael 所在node的 UID。


    打开 query tab页,键入以下查询并运行。

      {
      people(func: has(name)) {
      uid
      name
      age
      }
      }


      现在,我们可以从结果中复制 Michael所在node的UID了。



      在下面的查询中,将 MICHAEL_UID 替换为刚才复制的uid,并运行。

        {
        find_using_uid(func: uid(MICHAELS_UID)){
        uid
        name
        age
        }
        }



        可以看到,uid 函数返回的 node 正好匹配 Michael所在的node。


        如果对于上面的查询语法有疑问,可以阅读上篇文章


        更新 predicates


        我们也可以基于UID,更新node的一个或多个predicates。


        Michael最近庆祝了自己的41岁生日。我们来把他的年龄更新为41。


        打开mutate tab页 执行下面的语句。同样,别忘了将 MICHAEL_UID替换为真实的值。

          {
          "set":[
          {
          "uid": "MICHAELS_UID",
          "age": 41
          }
          ]
          }


          我们之前有使用 set 来创建新的nodes。但是当我们使用了已有node的UID时,它将会更新该node的predicates, 而不是创建一个新的node。


          可以看到,Michael的年龄变成了41。

            {
            find_using_uid(func: uid(MICHAELS_UID)){
            name
            age
            }
            }



            类似地,我们也可以给已有的node添加新的predicates。既然 Michael 所在node没有 country predicate,下面语句将为它添加这个predicate。

              {
              "set":[
              {
              "uid": "MICHAELS_UID",
              "country": "Australia"
              }
              ]
              }


              为已有的nodes添加edge


              也可以基于UIDs为已有的nodes添加edge。


              比方说,Leyla 开始关注 Michael


              我们知道,他俩的这个关系需要一个名为 follows 的edge来指明。


              首先,我们复制 Leyla 和 Michael 所在node的UID。


              然后,将下面的 LEYLA_UID和MICHAEL_UID替换为刚才复制的值,并执行它。

                {
                "set":[
                {
                "uid": "LEYLAS_UID",
                "follows": {
                "uid": "MICHAELS_UID"
                }
                }
                ]
                }


                遍历 edges


                Graph 数据库提供了一些特有的能力。Traversals(遍历) 是其一。


                Traversals解决的是有关nodes之间关系的问题。因此像这类查询——Michael关注了谁?—— 可以通过遍历 follows 关系查得。


                让我们运行一个 traversal 查询,并具体地理解一翻。

                  {
                  find_follower(func: uid(MICHAELS_UID)){
                  name
                  age
                  follows {
                  name
                  age
                  }
                  }
                  }


                  这是结果。


                  该项查询涉及3个部分:

                  • 定位出root nodes

                    首先,需要选中一个或多个用来遍历的起始nodes。它们被叫作 root nodes。在上面的查询中,我们使用 uid 函数将 Michael所在node 作为 root node。

                  • 选出需要遍历的edge

                    需要指定遍历哪个edge。接着,遍历将会沿着edge往下走,从一个node到它连接的另一个node。

                  • 指明需要返回的predicates

                    既然Michael只关注了一个人,该次遍历只会返回一个node。返回的是一个 2级nodes。root nodes此时是 1级nodes。同样,也需要指明2级nodes要返回哪些predicates。




                  我们也可以修改这个查询,利用2级nodes进一步遍历更深层次的nodes。下一段将继续探索这个问题。


                  多层遍历


                  第一层遍历返回的是Michael关注的人。下一层的遍历进一步返回了这些被Michael关注的人所关注的人。


                  该模式可以重复多次来实现多层遍历。随着遍历的深入,查询的层级也会一步一步加大。

                    {
                    find_follower(func: uid(MICHAELS_UID)) {
                    name
                    age
                    follows {
                    name
                    age
                    follows {
                    name
                    age
                    }
                    }
                    }
                    }



                    再深入一些: 

                      {
                      find_follower(func: uid(MICHAELS_UID)) {
                      name
                      age
                      follows {
                      name
                      age
                      follows {
                      name
                      age
                      follows {
                      name
                      age
                      }
                      }
                      }
                      }
                      }



                      这个查询真是太长了。有4层深。换句话说,查询的深度是4。你可能要问了,有没有什么内置的函数,使得多层遍历简单一些?


                      答案是 Yes!这正是 recurse() 函数要做的。


                      递归遍历


                      递归查询让多层级深度遍历变得简单。它让你可以轻易地遍历一个Graph的一部分。


                      以下面的递归查询为例,它实现的效果和上面的查询一样。但是体验上更好了。

                        {
                        find_follower(func: uid(MICHAELS_UID)) @recurse(depth: 4) {
                        name
                        age
                        follows
                        }
                        }


                        在上面的查询中,recurse函数从Michael所在节点开始遍历graph。你也可以选择任何其它的node作为起始node。depth参数指定遍历的深度。


                        执行的结果如下:


                        Edges有其方向性


                        在Dgraph中,edges是有方向的。


                        例如,follows edge 从Michael开始,然后指向Pawan。它有着方向性。


                        在Dgraph中沿着edge的方向遍历是再正常不过了。在后续的系列中,我们还将讨论反方向遍历edges。


                        删除predicate


                        node 的 predicates 可以使用 delete mutation 进行删除。下面是删除node中predicate的语法:

                          {
                          delete {
                          <UID> <predicate_name> * .
                          }
                          }


                          使用上面的语法,删除Michael的 age predicate:

                            {
                            delete {
                            <MICHAELS_UID> <age> * .
                            }
                            }



                            总结


                            本文讲述了Dgraph中基于UIDs的CRUD操作。我们同时也学习了 recurse() 函数。


                            下一回文章将介绍基于 predicates值的查询。


                            下次见喽。



                            文章转载自背井,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                            评论