参考:https://tour.dgraph.io/schema/1/
这个教程主要关于一个schema怎么样在dgraph里面运作,并且告诉我们怎么样去增加、更新、删除一个数据(也就是怎么变动(mutate)数据)的
一、增加、修改schema
dgraph里的schema描述了predicate的类型,当我们想要向已有的schema里添加数据时,我们新增就好了。但是如果我们想要向一个新的(还没创建的)schema里新增数据,我们有两个选择:
1.直接新增数据,dgraph会自动新增这个schema
2.先定义一个schema,再新增数据。
这两种方法都可以的。不过如果要用functions或是filter,predicate必须是被索引的,所以在这种情况下,我们需要先定义schema.
不知道下面两句想表达啥。。没头没尾的,直接贴出来好了
Alter schema to define data types and to add indexes.
Run to alter schema. The index allows applying filter functions, such as searching for all companies that participate in a particular industry.
示例:
industry: string @index(term) .
boss_of: uid .
二、新增、修改数据
现在schema已经被更新了,我们可以三个一组来新增数据了。
dgraph为每个数据节点创建它自己的内部的id,但是我们有时我们需要多次使用一个节点,就像下面例子中的_:company1一样:
{
set {
_:company1 <name> "CompanyABC" .
_:company2 <name> "The other company" .
_:company1 <industry> "Machinery" .
_:company2 <industry> "High Tech" .
_:jack <works_for> _:company1 .
_:ivy <works_for> _:company1 .
_:zoe <works_for> _:company1 .
_:jose <works_for> _:company2 .
_:alexei <works_for> _:company2 .
_:ivy <boss_of> _:jack .
_:alexei <boss_of> _:jose .
}
}
//运行结果如下:
{
"data": {
"code": "Success",
"message": "Done", "uids": { "alexei": "0x21", "company1": "0x22", "company2": "0x23", "ivy": "0x25", "jack": "0x24", "jose": "0x20", "zoe": "0x1f" } }, "extensions": { "server_latency": { "parsing_ns": 330152, "processing_ns": 8271549 }, "txn": { "start_ts": 86, "commit_ts": 87, "lin_read": { "ids": { "1": 65 } } } } }
技术上来说,这些是空节点,他们告诉dgraph去创建一个节点,给它一个内部id并且确认它能够被一致地使用。
运行了上面的代码之后,_:company1在dgraph中并不存在,我们也不能去搜索它。我们会发现_:company1已经变成了一个内部id(如上面的运行结果中的uids块),我们可以搜索这个内部id,使用方法func:uid(<uid_number>)。
让dgraph中的数据产生变化被称作为mutating数据。
三、外部标识
dgraph并不支持外部对节点设置id,如果一个应用的节点需要唯一的标识而不是由dgraph来定义,那这些节点需要声明为一个边(edges),由用户的应用来确保这些id的唯一性。
四、语言支持
语言标签应用于输入时的字符串上,如下:
_:myID <an_edge> "something"@en .
_:myID <an_edge> "某物"@zh-Hans .
也应用于搜索时的边上,如下:(原文链接https://tour.dgraph.io/basic/4/)
{
language_support(func: allofterms(name@hi, "अमित")) {
name@bn:hi:en
age
friend {
name@ko:ru
age
}
}
}
五、反向边
边都是有方向的,一个搜索不可以反向对边进行遍历。
有两个方法可以从两个方向对边进行查询:
1.自己把所有边的反向边都加上,然后把数据也加上。
2.使用@reverse 关键词,如下 :
boss_of: uid @reverse .
运行上面的变更,那么dgraph会计算所有的反向边。an_edge 的反向边表示为 ~an_edge.
至于数据模型,一些反向边依然有意义,比如boss_of边,或者friend边,有时并不总是双向的。
六、实践:聚合现有数据
我们已经新增了一个schema并且载入了一些公司数据,但是怎么样去聚合我们以前的朋友集到现在的公司呢?
不能使用空的节点,因为这些空的节点并不存在,所以我们需要用到uid.
以下为错误示例,因为_:sarah和_:company1都并不存在:
_:sarah <works_for> _:company1 .
以下为正确示例:
<uid-for-sarah> <works_for> <uid-for-company1> .
下面这一段用原文吧
Because the uid
picked by Dgraph is unique, we can’t help you this time. Use the uid
’s picked by your instance of Dgraph to write a mutation that links the company and friendship data. Hint: previous queries will tell you the uid
.
The process you’ve just done here would normally done programmatically - query the data to get the uid
’s, formulate the mutations, then batch the updates.
七、删除数据
有三种删除的方式:
<uid> <edge> <uid>/"value" .
删除一个单独的triple<uid> <edge> * .
删除一个边的所有的triple<uid> * * .
删除一个节点的所有的triples
下面的例子并不完全,uids应该是唯一的。
{
delete {
# Delete a single triple
<0x1c3eb> <name> "Steven" .
<0x1c3eb> <age> "38" .
# Delete all triples for a given edge
<0x1c3eb> <friend> * .
# Delete all triples for a given node
<0x1c3eb> * * .
}
}
八、谓语查询 (predicate query)
_predicate_查询的是一个节点的所有外连的边。
注意:设计一个图与schema和intent不同。因为任何一个节点可能也可能不会有其他节点有的所有的谓语。
Something to try: query for the outgoing edges of some people from the friends data and note how some have owns_pet
listed and some do not.
一般来说,大型图表通常表示的部分视图建模数据。我们的工作分析是理解数据的关系数据在处理空白或不完整的知识。
示例如下:
{
company(func: allofterms(name, "CompanyABC")) {
_predicate_
}
}
九、扩展predicate
expand(...predicates...)
被用来查询所有的谓语,而不是在查询语句中列出来(嗯???)。调用expand(_all_)
用来从每个符合条件的节点里查询所有的边 。expand可以层层嵌套。我们之后会说如何使用expand去查询一个特定的边集。
expand示例:
{
expand(func: allofterms(name, "Michael")) {
expand(_all_) {
expand(_all_) {
expand(_all_)
}
}
}
}