DQL-2.3.开始使用Dgraph-基本类型和操作

翻译自:这里

在前面的教程中,我们学习了使用uid的CRUD操作。我们还学习了遍历和递归遍历。

在本教程中,我们将学习Dgraph的基本类型以及如何查询它们。具体来说,我们将了解:

  • Dgraph中的基本数据类型。
  • 查询谓词值。
  • 索引。
  • 过滤节点。
  • 反向查询。

让我们从构建一个简单的博客应用程序的图形开始。下面是我们应用程序的Graph模型:

上面的图表有三个实体:作者Author、博客文章Blog post和标签Tag。图中的节点表示这些实体。在本教程的其余部分中,我们将把表示博客的节点称为博客文章节点,把表示标签的节点称为标签节点,以此类推。

从图模型中可以看出,这些实体是相关的:

  • 每个作者都有一篇或多篇博客文章。边published将博客与其作者联系起来。这些边从作者节点开始,指向博客文章节点。
  • 每个博客文章都有一个或多个标签。边tagged将博客文章与它们的标签联系起来。这些边从博客文章节点中出现并指向标签节点。

让我们来构建我们的图。

转到Ratel,单击突变选项卡,粘贴以下突变,然后单击Run。

{
 "set": [
  {
   "author_name": "John Campbell",
   "rating": 4.1,
   "published": [
    {
     "title": "Dgraph's recap of GraphQL Conf - Berlin 2019",
     "url": "https://blog.dgraph.io/post/graphql-conf-19/",
     "content": "We took part in the recently held GraphQL conference in Berlin. The experience was fascinating, and we were amazed by the high voltage enthusiasm in the GraphQL community. Now, we couldn’t help ourselves from sharing this with Dgraph’s community! This is the story of the GraphQL conference in Berlin.",
     "likes": 100,
     "dislikes": 4,
     "publish_time": "2018-06-25T02:30:00",
     "tagged": [
      {
       "uid": "_:graphql",
       "tag_name": "graphql"
      },
      {
       "uid": "_:devrel",
       "tag_name": "devrel"
      }
     ]
    },
    {
     "title": "Dgraph Labs wants you!",
     "url": "https://blog.dgraph.io/post/hiring-19/",
     "content": "We recently announced our successful Series A fundraise and, since then, many people have shown interest to join our team. We are very grateful to have so many people interested in joining our team! We also realized that the job openings were neither really up to date nor covered all of the roles that we are looking for. This is why we decided to spend some time rewriting them and the result is these six new job openings!.",
     "likes": 60,
     "dislikes": 2,
     "publish_time": "2018-08-25T03:45:00",
     "tagged": [
      {
       "uid": "_:hiring",
       "tag_name": "hiring"
      },
      {
       "uid": "_:careers",
       "tag_name": "careers"
      }
     ]
    }
   ]
  },
  {
   "author_name": "John Travis",
   "rating": 4.5,
   "published": [
    {
     "title": "How Dgraph Labs Raised Series A",
     "url": "https://blog.dgraph.io/post/how-dgraph-labs-raised-series-a/",
     "content": "I’m really excited to announce that Dgraph has raised $11.5M in Series A funding. This round is led by Redpoint Ventures, with investment from our previous lead, Bain Capital Ventures, and participation from all our existing investors – Blackbird, Grok and AirTree. With this round, Satish Dharmaraj joins Dgraph’s board of directors, which includes Salil Deshpande from Bain and myself. Their guidance is exactly what we need as we transition from building a product to bringing it to market. So, thanks to all our investors!.",
     "likes": 139,
     "dislikes": 6,
     "publish_time": "2019-07-11T01:45:00",
     "tagged": [
      {
       "uid": "_:annoucement",
       "tag_name": "annoucement"
      },
      {
       "uid": "_:funding",
       "tag_name": "funding"
      }
     ]
    },
    {
     "title": "Celebrating 10,000 GitHub Stars",
     "url": "https://blog.dgraph.io/post/10k-github-stars/",
     "content": "Dgraph is celebrating the milestone of reaching 10,000 GitHub stars 🎉. This wouldn’t have happened without all of you, so we want to thank the awesome community for being with us all the way along. This milestone comes at an exciting time for Dgraph.",
     "likes": 33,
     "dislikes": 12,
     "publish_time": "2017-03-11T01:45:00",
     "tagged": [
      {
       "uid": "_:devrel"
      },
      {
       "uid": "_:annoucement"
      }
     ]
    }
   ]
  },
  {
   "author_name": "Katie Perry",
   "rating": 3.9,
   "published": [
    {
     "title": "Migrating data from SQL to Dgraph!",
     "url": "https://blog.dgraph.io/post/migrating-from-sql-to-dgraph/",
     "content": "Dgraph is rapidly gaining reputation as an easy to use database to build apps upon. Many new users of Dgraph have existing relational databases that they want to migrate from. In particular, we get asked a lot about how to migrate data from MySQL to Dgraph. In this article, we present a tool that makes this migration really easy: all a user needs to do is write a small 3 lines configuration file and type in 2 commands. In essence, this tool bridges one of the best technologies of the 20th century with one of the best ones of the 21st (if you ask us).",
     "likes": 20,
     "dislikes": 1,
     "publish_time": "2018-08-25T01:44:00",
     "tagged": [
      {
       "uid": "_:tutorial",
       "tag_name": "tutorial"
      }
     ]
    },
    {
     "title": "Building a To-Do List React App with Dgraph",
     "url": "https://blog.dgraph.io/post/building-todo-list-react-dgraph/",
     "content": "In this tutorial we will build a To-Do List application using React JavaScript library and Dgraph as a backend database. We will use dgraph-js-http — a library designed to greatly simplify the life of JavaScript developers when accessing Dgraph databases.",
     "likes": 97,
     "dislikes": 5,
     "publish_time": "2019-02-11T03:33:00",
     "tagged": [
      {
       "uid": "_:tutorial"
      },
      {
       "uid": "_:devrel"
      },
      {
       "uid": "_:javascript",
       "tag_name": "javascript"
      }
     ]
    }
   ]
  }
 ]
}

我们的图表准备好了!

我们的图:

  • 三个蓝色的作者节点。
  • 每个作者都有两篇博文——总共六篇——由绿色节点表示。
  • 博客文章的标签是粉红色的。您可以看到有8个独特的标记,其中一些博客共享一个公共标签。

谓词的数据类型

Dgraph自动检测其谓词的数据类型。您可以使用Ratel UI查看自动检测的数据类型。

单击左边的schema选项卡,然后选中Type列。您将看到谓词名称及其对应的数据类型。

这些数据类型包括string、float、int和uid。除此之外,Dgraph还提供了另外三种基本数据类型:geo、dateTime和bool。

uid类型表示两个节点之间的谓词。换句话说,它们表示连接两个节点的边。

您可能已经注意到,published 和 tagged 谓词的类型是uid数组([uid])。UID数组表示UID的集合。这用于表示一对多关系。

例如,我们知道一个作者可以发布多个博客。因此,从给定的作者节点中可能出现多个published边,每个边指向作者的不同博客文章。

Dgraph的v1.1版本引入了类型系统特性Type。这个特性使得通过分组一个或多个谓词来创建自定义数据类型(Type)。但在本教程中,我们只关注基本数据类型。

另外,请注意索引列Indices中没有条目。稍后我们将详细讨论索引。

查询谓词值

首先,让我们查询所有的作者和他们的评级rating:

{
  authors_and_ratings(func: has(author_name)) {
    uid
    author_name
    rating
  }
}

我们的数据集中总共有3个作者。现在,让我们找出最好的作者。让我们查询评分为4.0或更高的作者。

为了实现我们的目标,我们需要一种方法来选择满足特定标准的节点(例如,评级> 4.0)。可以通过使用Dgraph的内置比较器函数来实现这一点。以下是Dgraph中可用的比较器函数列表:

比较器函数名 全称
eq equals to
lt less than
le less than or equal to
gt greater than
ge greater than or equal to

在Dgraph中总共有五个比较器函数。你可以在你的查询中使用它们中的任何一个和func关键字一起。

比较器函数有两个参数。一个是谓词名,另一个是它的可比值。这里有几个例子。

使用案例 描述
func: eq(age, 60) 返回年龄谓词等于60的节点。
func: gt(likes, 100) 返回值为likes谓词大于100的节点。
func: le(dislikes, 10) 返回值为dislikes谓词小于或等于10的节点。

现在,猜猜我们应该使用哪个比较器函数来选择评分为4.0或更高的作者节点。如果你认为它应该使用大于或等于(ge)函数,那么你是对的!

我们来试一下。

{
  best_authors(func: ge(rating, 4.0)) {
    uid
    author_name
    rating
  }
}

我们有一个错误!缺少评级谓词的索引。您不能查询谓词的值,除非您为它添加了索引。

让我们学习更多关于Dgraph中的索引以及如何添加它们。

Dgraph中的索引

索引用于加快对谓词的查询。当需要时,它们必须显式地添加到谓词中。也就是说,仅当您需要查询谓词的值时。

此外,不需要在一开始就预测要添加的索引。您可以在进行过程中添加它们。

Dgraph提供不同类型的索引。索引的选择取决于谓词的数据类型。

下面是包含数据类型和可应用于它们的索引集的表。

数据类型 可用的索引类型
int int
float float
string hash, exact, term, fulltext, trigram
bool bool
geo geo
dateTime year, month, day, hour

只有string和dateTime数据类型可以选择多个索引类型。

让我们在评级谓词上创建一个索引。Ratel UI让添加索引变得超级简单。

以下是步骤的顺序:

  • 转到左边的Schema模式选项卡。
  • 从列表中点击rating评级谓词。
  • 在右侧的属性UI中勾选索引index选项。

我们成功地为评级谓词添加了索引!让我们重新运行前面的查询。

我们成功地查询了评级为4.0或更高的Author节点。我们也获取这些作者的Blog帖子怎么样?

我们已经知道,边published从一个作者节点到一个博客帖子节点。因此,获取作者节点的博客帖子非常简单。我们需要从作者节点开始遍历published边。

{
  authors_and_ratings(func: ge(rating, 4.0)) {
    uid
    author_name
    rating
    published {
      title
      content
      dislikes
    }
  }
}

类似地,让我们扩展前面的查询以获取这些博客文章的标签。

{
  authors_and_ratings(func: ge(rating, 4.0)) {
    uid
    author_name
    rating
    published {
      title
      content
      dislikes
      tagged {
        tag_name
      }
    }
  }
}


注意:作者节点是蓝色的,博客帖子是绿色的,标签是粉色的。

结果中有两个作者、四篇博客文章和它们的标签。如果你仔细看看结果,有一篇博文的dislikes是12。

让我们只过滤和获取流行的博客文章。让我们只查询那些博客帖子dislikes少于10个的博客帖子。

我们可以在遍历过程中过滤节点吗?是的,我们可以!让我们在下一节学习如何做到这一点。

过滤遍历

我们可以使用@filter指令过滤遍历的结果。你可以使用@filter指令使用任何Dgraph的比较器函数。您应该使用lt比较器函数来过滤dislikes少于10个的博客文章。

这是查询。

{
  authors_and_ratings(func: ge(rating, 4.0)) {
    author_name
    rating

    published @filter(lt(dislikes, 10)) {
      title
      likes
      dislikes
      tagged {
        tag_name
      }
    }
  }
}

查询返回:

现在,结果中只有三个博客。dislikes有12个的博客被过滤掉。

让我们运行下面的查询并找到数据库中的所有标签。

{
  all_tags(func: has(tag_name)) {
    tag_name
  }
}

我们得到了数据库中所有的标签。我最喜欢的标签是devrel。哪个是你的吗?

在下一节中,让我们找到所有标签为devrel的博客文章。

查询字符串谓词

tag_name谓词表示标记的名称。它的类型是string。下面是获取所有标记为devrel的博客文章的步骤。

  • 找到将tag_name谓词的值设置为devrel的根节点。我们可以使用eq比较器函数来做到这一点。
  • 在运行查询之前,不要忘记向tag_name谓词添加一个索引。
  • 从devrel的标记节点开始沿边tagged遍历。

让我们首先向tag_name谓词添加一个索引。转到Ratel,从列表中单击tag_name谓词。

您可以看到,索引有五种选择,可以应用于任何字符串谓词。fulltext、term和trigram是高级字符串索引。我们将在后面的文章中详细讨论它们。

关于字符串类型索引和比较器函数的使用有一些约束。

例如,只有精确索引exact与le、ge、lt和gt内置函数兼容。如果使用任何其他索引设置字符串谓词并运行上述比较器,则查询将失败。

尽管五个字符串类型索引中的任何一个都与eq函数兼容,但eq比较器使用的哈希索引hash通常是性能最好的。

让我们将哈希索引hash添加到tag_name谓词。

让我们使用eq比较器并获取将tag_name设置为devrel的根节点。

{
  devrel_tag(func: eq(tag_name,"devrel")) {
    tag_name
  }
}

我们终于得到了我们想要的节点!

我们知道博客文章节点通过边tagged连接到它们的标记节点。你认为从tag_name为devrel的标签节点遍历可以得到博客文章吗?让我们试试吧!

{
  devrel_tag(func: eq(tag_name,"devrel")) {
    tag_name
      tagged {
        title
        content
    }
  }
}

看起来查询没有工作!它没有回复我们任何博客帖子!不要感到惊讶,因为这是预料之中的。

让我们再次观察我们的Graph模型。

我们知道Dgraph中的边是有方向的。您可以看到边tagged从博客文章节点指向标记节点。

沿着边的方向遍历对于Dgraph来说是很自然的。因此,您可以通过边tagged从任何博客文章节点遍历到其标记节点。

但如果要从另一个方向穿越,就需要你朝着边缘的相反方向移动。您仍然可以通过在查询中添加一个波浪号()来做到这一点。波浪号()必须添加在要遍历的边缘名称的开头。

让我们在标记的边缘tagged开始添加波浪号(~),并发起反向边缘遍历。

{
  devrel_tag(func: eq(tag_name,"devrel")) {
    tag_name

    ~tagged {
      title
      content
    }
  }
}

我们有一个错误!

反向遍历需要在其谓词上有一个索引。

让我们切换到Ratel,将反向索引添加到边上。

让我们重新运行反边遍历。

{
  devrel_tag(func: eq(tag_name, "devrel")) {
    tag_name

    ~tagged {
      title
      content
    }
  }
}

唷!现在我们得到了所有标记为devrel的博客文章。

类似地,您可以扩展该查询以查找这些博客文章的作者。它要求您反向遍历谓词边published。

让我们将反向索引添加到边published。

现在,让我们运行以下查询。

{
  devrel_tag(func: eq(tag_name,"devrel")) {
    tag_name

    ~tagged {
      title
      content

      ~published {
        author_name
      }
    }
  }
}

在前面的查询中,我们以相反的顺序遍历整个图。从标记节点开始,遍历到作者节点。

posted @ 2021-12-07 15:48  KILLNPE  阅读(397)  评论(0编辑  收藏  举报