go实现dgraph的各种操作
go实现dgraph的各种操作
import "github.com/dgraph-io/dgo"
import "github.com/dgraph-io/dgo/protos/api"
import "google.golang.org/grpc"
我在这篇博客将会做以下的工作:
- 初始化Node
- 添加Node
- 查询数据库
- 为数据库添加Edge , 即 添加predicate<朋友>
- 更新数据库
- 删除Node
之前我已经实现了用dgraph的http客户端实现 dgraph 的各种操作, 但是在 go 客户端实现和 http 客户端实现还是存在着比较大的区别. 因此, 我就写了这篇博客用于记录.
哦, 对了, 另外还有一个关键就是, 在我写这篇博客的时候 dgraph 在GODOC和GOWalker的文档都还没补全, 有很多方法都还只是写了个名, 甚至都没介绍, 对新手非常不友好.
初始化数据库
此处, 我将创建五个用户作为基础数据库
初始化Person的结构体, 表的属性从中也可以看出
type Person struct{
Uid string `json:"uid,omitempty"`
Name string `json:"name,omitempty"`
From string `json:"from,omitempty"`
NameOFcn string `json:"nameOFcn,omitempty"`
NameOFjp string `json:"nameOFjp,omitempty"`
NameOFen string `json:"nameOFen,omitempty"`
Age int `json:"age,omitempty"`
Friend []Person `json:"friend,omitempty"`
}
插入五个人的数据
var (
dgraph = flag.String("d", "127.0.0.1:9080", "Dgraph server address")
)
func main() {
flag.Parse()
conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
p1 := Person{
Name: "wangha",
Age: 17,
From: "China",
NameOFen: "wangha",
NameOFcn: "王哈",
NameOFjp: "王ハ",
}
p2 := Person{
Name: "chenchao",
Age: 22,
From: "China",
NameOFen: "ChaoChen",
NameOFcn: "陈超",
}
p3 := Person{
Name: "xhe",
Age: 18,
From: "Japan",
NameOFen: "wanghe",
NameOFcn: "x鹤",
}
p4 := Person{
Name: "changyang",
Age: 19,
From: "England",
NameOFcn: "常飏",
}
p5 := Person{
Name: "yetao",
Age: 18,
From: "Russian",
NameOFen: "TaoYe",
NameOFcn: "叶掏",
}
op := &api.Operation{}
op.Schema = `
name: string .
age: int .
from: string .
nameOFcn: string @index(term) .
nameOFjp: string @index(term) .
nameOFen: string @index(term) .
`
ctx := context.Background()
if err := dg.Alter(ctx, op); err != nil {
log.Fatal(err)
}
mu := &api.Mutation{
CommitNow: true,
}
var p = [5]Person{p1,p2,p3,p4,p5}
for _,x := range p {
pb, err := json.Marshal(x)
if err != nil {
log.Println(err)
}
mu.SetJson = pb
_,err = dg.NewTxn().Mutate(ctx, mu)
if err != nil {
log.Println(err)
}
}
}
我们可以从http客户端查看验证是否插入成功
可以看出, 插入成功了
添加Node
此处新注册了一位朋友, 我们需要将他添加到 dgprah 中
和前面的步骤基本一样, 只是少了初始化 schema 的步骤
func main() {
flag.Parse()
conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
ctx := context.Background()
mu := &api.Mutation{
CommitNow: true,
}
type arrays struct{
Uids []Person `json:"info"`
}
t := Person{
Name : "yaozhao",
Age : 24,
From : "M78Star",
NameOFcn : "姚X",
NameOFjp : "姚飞机",
NameOFen : "ZhaoYao",
}
pb, err := json.Marshal(t)
if err != nil {
log.Println(err)
}
mu.SetJson = pb
assign,err := dg.NewTxn().Mutate(ctx,mu)
if err != nil{
log.Println(err)
}
fmt.Printf("assign: %v \n",assign)
}
查询
此时,我们查询有关于Name="yaozhao"的信息
func main() {
flag.Parse()
conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
ctx := context.Background()
vars := make(map[string]string)
vars["$enname"] = "ZhaoYao"
q := `query wanghainfo($enname: string){
info(func: eq(nameOFen, $enname)){
uid
expand(_all_)
}
}`
resp, err := dg.NewTxn().QueryWithVars(ctx,q,vars)
if err != nil {
log.Println(err)
}
type arrays struct{
Uids []Person `json:"info"`
}
var r arrays
err = json.Unmarshal(resp.Json, &r)
if err != nil{
log.Println(err)
}
log.Println(string(resp.Json))
log.Println(r.Uids[0].Uid)
}
可以看到结果如下:
添加Edge: predicate<friend>
我在 json 格式进行Mutate时, 没有找到相关的添加Edge的方法, 因此我改为用NQuad格式.
NQuad介绍: RDF/NQuad
func main() {
flag.Parse()
conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
ctx := context.Background()
mu := &api.Mutation{
CommitNow: true,
}
type arrays struct{
Uids []Person `json:"info"`
}
var1 := make(map[string]string)
var1["$enname"] = "wangha"
q1 := `query wanghainfo($enname: string){
info(func: eq(nameOFen, $enname)){
uid
}
}`
resp, err := dg.NewTxn().QueryWithVars(ctx,q1,var1)
if err != nil {
log.Println(err)
}
var r1 arrays
var r2 arrays
err = json.Unmarshal(resp.Json, &r1)
if err != nil{
log.Println(err)
}
Uid_wangha := r1.Uids[0].Uid
var1["$enname"] = "TaoYe"
q2 := `query wanghainfo($enname: string){
info(func: eq(nameOFen, $enname)){
uid
}
}`
resp, err = dg.NewTxn().QueryWithVars(ctx,q2,var1)
if err != nil{
log.Println(err)
}
err = json.Unmarshal(resp.Json, &r2)
if err != nil{
log.Println(err)
}
Uid_TaoYe := r2.Uids[0].Uid
t :=fmt.Sprintf("<%s> <friend> <%s> .",Uid_wangha,Uid_TaoYe)
mu.SetNquads = []byte(t)
_,err = dg.NewTxn().Mutate(ctx,mu)
if err != nil{
log.Println(err)
}
}
验证:
更新数据
若在此时, 我发现我的数据弄错了
用户nameOFen="ZhaoYao"的用户age实际应该为20, 此时, 同样是用NQuad来更新数据
func main() {
flag.Parse()
conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
ctx := context.Background()
mu := &api.Mutation{
CommitNow: true,
}
type arrays struct{
Uids []Person `json:"info"`
}
var1 := make(map[string]string)
var1["$enname"] = "ZhaoYao"
q1 := `query wanghainfo($enname: string){
info(func: eq(nameOFen, $enname)){
uid
}
}`
resp, err := dg.NewTxn().QueryWithVars(ctx,q1,var1)
if err != nil {
log.Println(err)
}
var r1 arrays
err = json.Unmarshal(resp.Json, &r1)
if err != nil{
log.Println(err)
}
Uid_wangha := r1.Uids[0].Uid
log.Println(Uid_wangha)
t := fmt.Sprintf("<%s> <age> \"%s\" .",Uid_wangha,"20")
mu.SetNquads = []byte(t)
assign,err := dg.NewTxn().Mutate(ctx,mu)
if err != nil{
log.Println(err)
}
fmt.Printf("assign: %v",assign)
}
可以看到结果:
更新成功
删除用户
删除用户时, dgraph规定了无法删除Uid <subject> , 只能删除<predicate>和<object>
使用了&api.Mutation内规定的方法去删除
func main() {
flag.Parse()
conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
ctx := context.Background()
vars := make(map[string]string)
vars["$enname"] = "ZhaoYao"
q := `query wanghainfo($enname: string){
info(func: eq(nameOFen, $enname)){
uid
}
}`
resp, err := dg.NewTxn().QueryWithVars(ctx,q,vars)
if err != nil {
log.Println(err)
}
type arrays struct{
Uids []Person `json:"info"`
}
var r arrays
err = json.Unmarshal(resp.Json, &r)
if err != nil{
log.Println(err)
}
log.Println(string(resp.Json))
log.Println(r.Uids[0].Uid)
d := map[string]string{"uid":string(r.Uids[0].Uid)}
pb, err := json.Marshal(d)
mu := &api.Mutation{
CommitNow: true,
DeleteJson: pb,
}
assign,err := dg.NewTxn().Mutate(ctx, mu)
if err != nil{
log.Println(err)
}
fmt.Printf("assign: %v \n",assign)
}
再次查询, 数据已经消失
写在最后
dgraph 是一个非常强的分布式 NoSql , 想弄懂了真的得看很多遍技术文档
以下链接可能在你学习的时候会有所帮助
Mutate : https://docs.dgraph.io/mutations/
Query : https://docs.dgraph.io/query-language/
Client : https://docs.dgraph.io/clients/
Dgo : https://gowalker.org/github.com/dgraph-io/dgo
Api : https://gowalker.org/github.com/dgraph-io/dgo/protos/api#Assigned
go实现dgraph的各种操作的更多相关文章
- 图数据库项目DGraph的前世今生
本文由云+社区发表 作者:ManishRai Jain 作者:ManishRai Jain Dgraph Labs创始人 版权声明:本文由腾讯云数据库产品团队整理,页面原始内容来自于db weekly ...
- dgraph 基本查询语法 三
这部分主要是查询块.查询变量.聚合操作 多名称查询 实际上就是类似多个查询数据的拼接 格式: { caro(func: allofterms(name@en, "Marc Caro" ...
- dgraph 基本查询语法 二
这部分主要是mutation 操作,(就是增加.删除操作) 参考git 项目 https://github.com/rongfengliang/dgraph-docker-compose-deploy ...
- dgraph 使用简介
dgraph 简介 dgraph 使用示例(基于 golang) golang client 安装 创建 schema 数据的 CURD 事务 总结 dgraph 简介 dgraph 是基于 gola ...
- 关于DOM的操作以及性能优化问题-重绘重排
写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...
- Sql Server系列:分区表操作
1. 分区表简介 分区表在逻辑上是一个表,而物理上是多个表.从用户角度来看,分区表和普通表是一样的.使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性. 分区表是把数据按设 ...
- C# ini文件操作【源码下载】
介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...
- js学习笔记:操作iframe
iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...
- jquery和Js的区别和基础操作
jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...
随机推荐
- js 滚轮控制图片缩放大小和拖动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 七、Android动画
Android的动画可以分为三种:View动画.帧动画和属性动画,帧动画也属于View动画的一种,只不过它和平移.旋转等常见的View动画在表现形式上略有不同而已. 1.View动画 平移动画:Tra ...
- tomat 欢迎页面设置在WEB-INF目录下时不显示问题
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://w ...
- APICloud Studio2新建应用报错和检出错误
今天心血来潮,闲暇时间想做个移动应用app,听一哥们说APICloud开发app很方便,就查询了一下,看了之后简直就是热血沸腾,我感觉正是我一直要找的工具 信心满满的开始着手使用,看了一下介绍我选择了 ...
- (爬虫)urllib库
一.爬虫简介 什么是爬虫?通俗来讲爬虫就是爬取网页数据的程序. 要了解爬虫,还需要了解HTTP协议和HTTPS协议:HTTP协议是超文本传输协议,是一种发布和接收HTML页面的传输协议:HTTPS协议 ...
- 【shell实例】定时21:00-21:05,循环调用DSQL脚本,其它时段自动退出
1.功能描述: 每日21:00定时调起test.sh,循环调起DSQL脚本test.dsql,直到21:05程序自动退出,捕获日志到相应log文件中. 2.日志文件: (1)日期.log文件中含Err ...
- ASP.NET Core 2.2 : 十七.Action的执行(Endpoint.RequestDelegate后面的故事)
上一章介绍了经过路由的处理,一个请求找到了具体处理这个请求的EndPoint,并最终执行它的RequestDelegate方法来处理这个Httpcontext.本章继续这个处理进程,按照惯例,依然通过 ...
- .NET 增加扩展方法
声明:通过一个js的实例来告诉你C#也可以实现这样的效果. 在JS中是这样实现的: 你是否见过JS中给系统默认Array对象增加一个自定义查重方法contains 在没有给Array原型上增加cont ...
- elementUi、iview、ant Design源码button结构篇
在看elementUI的button组件的时候,一起和iview.ant Design的button组件比 较功能.样式.代码结构,看他们的一些不同点,不同的写法哪种会好些,button的对外开放的功 ...
- java接口测试入门
一.什么是接口 接口是前端和后端的数据通道 二.如何获取接口 1.开发不提供接口文档,通过抓包工具比如fiddler进行抓取,如下: 步骤一:设置浏览器(比如火狐)代理 步骤二:设置url过滤器,进入 ...