java dgraph spring

在项目里使用dgraph构建了关联图谱,简单写个不是用例的用例记录一下:
dgraph的docker-compose.yml:

version: "3.2"
services:
  zero:
    image: dgraph/dgraph:latest
    volumes:
      - /tmp/data:/dgraph
    ports:
      - 5080:5080
      - 6080:6080
    restart: on-failure
    command: dgraph zero --my=zero:5080
  alpha:
    image: dgraph/dgraph:latest
    volumes:
      - /tmp/data:/dgraph
    ports:
      - 8080:8080
      - 9080:9080
    restart: on-failure
    command: dgraph alpha --my=alpha:7080 --zero=zero:5080 --whitelist 172.17.0.0:172.20.0.0,192.168.1.1 --query_edge_limit 10000000 --lru_mb 4096
  ratel:
    image: dgraph/dgraph:latest
    ports:
      - 8000:8000
    command: dgraph-ratel

启动:docker-compose up -d

启动之后访问ratel:http://127.0.0.1:8000进入客户端,注意ratel是通过8080端口连接的alpha
控制台可以看出来对dgraph中数据的操作主要是两类,一类是query,一类是mutate,增删改都属于突变操作

添加dgraph中的架构:
name,age,sex表示人的属性(谓词,边),friend表示人与人之间的关系,dgraph节点间的关系是有方向性的 A --> B 表示A有B这样一个朋友,但是B不是A的朋友,~ 表示关系是双向的 A --> B同时存在B --> A
在这里插入图片描述
类别,增加Person这个类别,把name,age,sex归属给Person这个类别
在这里插入图片描述

<age>: int .
<friend>: uid @reverse .
<name>: string @index(exact) .
<sex>: string .
type <Person> {
	age
	name
	sex
}

存入一条数据:
在这里插入图片描述
用作查询的字段需要添加为索引:
在这里插入图片描述
查询:
在这里插入图片描述
再添加几个数据节点
创建关系:p1和p2是朋友,p2和p3是朋友,p3和p4是朋友。这里是直接看着uid构建的,代码中的话需要记录下返回的id或者查询出满足条件的id再构建关系
在这里插入图片描述
创建节点之间的关系,都是边
在这里插入图片描述

//rdf方式同时创建多个关系
{
 set {
<0x2>  <friend>  <0x3> . 
<0x3>  <friend>  <0x4> .
 }
}

查找p1的朋友
在这里插入图片描述
查询p1的朋友,递归查询,深度为4,p1本身是第一层,往下再3个深度
在这里插入图片描述
再增加一个节点p5,p5对p1只算半个朋友,关系上可以添加标签
在这里插入图片描述
边的方向性:
在这里插入图片描述
这时候查询应该还有p1–>p2–>p3–>p4的边,但是加上这个节点后没有了,有点不对。出现这个情况是因为在设置类型的时候friend关系没有设置成list类型,此时从p1节点只能存在一条friend类型的边,与p5建立关联后便与p1断了联系

Springboot中集成dgraph,用的dgraph4j,这个客户端对java而言并不友好,就只是把ratel里面写的语句拼起来通过rpc协议发送给客户端而已,用例和资料也不多,这方面neo4j成熟太多了,不过语句并不是很复杂,其实也可以通过xml封装,类似mysql的mapper文件。
引入包增加配置类

<dependency>
        <groupId>io.dgraph</groupId>
        <artifactId>dgraph4j</artifactId>
        <version>21.03.1</version>
</dependency>
@Configuration
public class DgraphConfig {
    @Value("${dgraph.ip}")
    private String ip;
    @Value("${dgraph.port}")
    private String port;

    @Bean
    public DgraphClient dgraphClient() {

        ManagedChannel channel1 = ManagedChannelBuilder
                .forAddress(ip, Integer.valueOf(post)).usePlaintext()
                .build();
        DgraphGrpc.DgraphStub stub1 = DgraphGrpc.newStub(channel1);
		//多个集群节点
       /* ManagedChannel channel2 = ManagedChannelBuilder
                .forAddress("localhost", 9082)
                .usePlaintext().build();
        DgraphGrpc.DgraphStub stub2 = DgraphGrpc.newStub(channel2);

        ManagedChannel channel3 = ManagedChannelBuilder
                .forAddress("localhost", 9083)
                .usePlaintext().build();
        DgraphGrpc.DgraphStub stub3 = DgraphGrpc.newStub(channel3);*/

//        DgraphClient dgraphClient = new DgraphClient(stub1, stub2, stub3);
        return new DgraphClient(stub1);
    }
}

创建Person类

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class Person {
    private Integer age;
    private String  name;
    private String sex;
}

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.protobuf.ByteString;
import io.dgraph.DgraphClient;
import io.dgraph.DgraphProto;
import io.dgraph.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
//代码并没有做测试,但是项目里写过一些,应该不会错太多的吧
@Component
public class Mutate {
    @Autowired
    DgraphClient dgraphClient;
    @Autowired
    ObjectMapper objectMapper;

    //添加一个person节点
    public void addPersion() {
        Transaction transaction = null;
        try {
            Person person = new Person().setAge(18).setName("张三").setSex("M");
            transaction = dgraphClient.newTransaction();
            DgraphProto.Mutation mutation = DgraphProto.Mutation.newBuilder().setSetJson(ByteString.copyFromUtf8(objectMapper.writeValueAsString(person))).build();
            DgraphProto.Response mutate = transaction.mutate(mutation);
            //成功时候可以取到存入节点的uid
            List<String> uidList = new ArrayList<String>( mutate.getUidsMap().values());
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != transaction) {
                transaction.discard();
            }
        }

    }
    
    //查询一个节点
    static String queryPersonByName = "query person($name:string){\n" +
            "  person(func: eq(name,$name)) {\n" +
            "        name\n" +
            "        age\n" +
            "        sex\n" +
            "\t}\n" +
            "}";
    public Person queryPersonByName(String name) {
        HashMap vars = new HashMap<String,String>() {{
            put("$personName", name);
        }};
        try {
            DgraphProto.Response res = dgraphClient.newTransaction().queryWithVars(queryPersonByName, vars);
            return objectMapper.readValue(res.getJson().toStringUtf8(),Person.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    //创建两个节点之间的关系
   public void createEdgesByRdf() {
        //带\n换行的多行就是批量创建
       String rdf = "<0x1>  <friend>  <0x2> .\n<0x2>  <friend>  <0x3>";
       Transaction transaction = null;
       try {
           transaction = dgraphClient.newTransaction();
           DgraphProto.Mutation mutation = DgraphProto.Mutation.newBuilder()
                            .setSetNquads(ByteString.copyFromUtf8(rdf))
                            .build();
           transaction.mutate(mutation);
           transaction.commit();
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           if (null != transaction) {
                transaction.discard();
           }
       }
    }

    //查询一个人的朋友
    static String queryFriendsByName = "query data($name:string,$depth:string){\n" +
            "  data(func: eq(name,$name)) @recurse(loop: false, depth: $depth) {\n" +
            "    name\n" +
            "    age\n" +
            "    sex\n" +
            "    friend @facets\n" +
            "\t}\n" +
            "}";
    public JsonNode queryFriendsByName(String name, String depth) {
        HashMap param = new HashMap<String,String>() {{
            put("$name", name);
            put("$depth", depth);
        }};
        DgraphProto.Response res ;
        try {
            res = dgraphClient.newTransaction().queryWithVars(queryFriendsByName, param);
            String resJsonStr = res.getJson().toStringUtf8();
            JsonNode jsonNode = objectMapper.readTree(resJsonStr);
            //data是传入的query函数的名称,queryFriendsByName中query的data,如果改成node,那么返回的数据名称就是node
            if (null != jsonNode && jsonNode.has("data") && jsonNode.get("data").size() > 0) {
                return jsonNode.get("data");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值