一、gStore数据库探索
gStore是面向RDF知识图谱的开源图数据库系统,支持复杂的SPARQL查询及有效的增删改操作,支持海量三元组规模的RDF知识图谱的数据管理任务。而gStore云平台是为了方便用户使用搭建的云服务web平台,用户可以在该平台上进行数据库管理(包括数据集构建、删除、导出等操作),也可以实现数据库查询及结果可视化,满足了广大gStore用户的基本需求。
1.构建数据库
执行bin/gbuild jinrong ./homework/jinrong.nt
构建图数据库
2. 查看数据库列表
执行bin/gshow
:
3. 数据库状态查询
执行bin/gmonitor jinrong
:
二. 任务要求
作业目标:利用提供的金融数据集,搭建以gStore为管理平台的小型金融知识图谱;并实现任务一、任务二、任务三的功能,返回正确的结果。(建议将gstore作为知识图谱存储介质,自己搭建应用平台完成实验)
数据集:本数据集是一部分清洗好的股东持股关系三元组数据jinrong.nt文件,主语是公司的名称,宾语是股东的名称,在使用时需要先上传到gStore云端。数据集放在百度网盘中,里面有数据内容的简单介绍。
任务一:按照任务一将数据上传到gStore云平台或者直接使用将数据集中的jinrong.nt文件上传到gStore云平台。利用构建好的知识图谱,编写sparql语句查询两个公司之间的关联路径(2-hop)。例如输入公司“招商局轮船股份有限公司”和“招商银行股份有限公司”,得到这两家公司之间的所有路径。
**任务二:**编写sparql语言实现多层股权的穿透式查询,可以根据指定层数获得对应层级的股东,例如:输入“招商局轮船股份有限公司””和层数3,就会把“招商局轮船股份有限公司”所对应公司所有三层以内的公司找出来。
**任务三:**编写sparql语言实现环形持股查询,判断两家公司是否存在环形持股现象,环形持股是指两家公司彼此持有对方的股份。例如:输入“A”和“C”,判断两家公司是否存在环形持股。
三、源码说明
附件源码简单说明:
- hw.java:程序启动类,运行main方法启动
- Client.java:为程序界面类,负责界面及信息显示
- TaskStrategy.java:抽象策略接口,定义了三个方法RunTask、GetSQL、ShowResult
- Task1.java、Task2.java、Task3.java:具体策略类,对应任务一、任务二、任务三
四、查询结果
1. 任务一
-
举例:如果输入“招商局轮船股份有限公司”和“深圳市晏清投资发展有限公司”,则相应的sparql语句如下:
PREFIX : <file:///F:/d2r-server-0.7/holder8.nt#holder_copy/> SELECT ?x ?p WHERE { { :招商局轮船股份有限公司 ?x :深圳市晏清投资发展有限公司. } union { :深圳市晏清投资发展有限公司 ?x :招商局轮船股份有限公司. } union { ?p ?b :深圳市晏清投资发展有限公司. :招商局轮船股份有限公司 ?c ?p. } union { ?p ?b :招商局轮船股份有限公司. :深圳市晏清投资发展有限公司 ?c ?p. } }
-
运行hw.java中的main方法,输入:招商局轮船股份有限公司 深圳市晏清投资发展有限公司
-
输入:招商局轮船股份有限公司 招商银行股份有限公司
-
输入:A 招商银行股份有限公司
2. 任务二(未解决)
-
举例:如果输入:公司名称 层数,则对应的sparql语句如下:
PREFIX : <file:///F:/d2r-server-0.7/holder8.nt#holder_copy/> SELECT (kHopReachablePath(?x, :公司名称, true, 层数, {}) AS ?y) WHERE { }
-
运行hw.java中的main方法,输入 :招商局轮船股份有限公司 3
查询结果为:
{
"head": {
"link": [],
"vars": [
"y"
]
},
"results": {
"bindings": [
{
"y": {
"type": "literal",
"value": "{\"paths\":[{\"src\":\"\",\"dst\":\"\",\"edges\":[],\"nodes\":[]}]}"
}
}
]
},
"StatusCode": 0,
"StatusMsg": "success",
"AnsNum": 1,
"OutputLimit": -1,
"ThreadId": "140116571899648",
"QueryTime": "��"
}
sql代码思路:使用SELECT (kHopReachablePath(?x, :公司名称, true, 层数, {}) AS ?y) WHERE { }
K 跳可达性查询,返回层数k以内可以到达公司节点的所有节点。
现存问题:通过ghttp发送sparql请求并解析json数据,并没有获取到对应的路径节点信息,多次调试也没有将问题解决
目前想法:控制好变量,用java写了个递归,将所有情况(1~k层内)的sparql语句用union拼起来,再ghttp执行sparql得到返回结果?
3. 任务三
-
举例:输入:A C 则对应的sparql语句为:
PREFIX : <file:///F:/d2r-server-0.7/holder8.nt#holder_copy/> select (cycleBoolean(:A, :C, true, {}) as ?x)where{ }
-
运行hw.java中的main方法,输入: A C
-
输入:A 深圳市晏清投资发展有限公司
五、附java源码:
public class hw {
public static void main(String[] args) {
new Client().start();
}
}
public class Client {
//连接对象
GstoreConnector gc;
Scanner scanner = new Scanner(System.in);
//策略对象
TaskStrategy taskStrategy = null;
public Client(){
String IP = "127.0.0.1";
int Port = 9000;
String username = "root";
String password = "123456";
// start a gc with given IP, Port, username and password
gc = new GstoreConnector(IP, Port, username, password);
//build
gc.build("jinrong", "./homework/jinrong.nt");
//load
gc.load("jinrong");
//加载完成
// System.out.println("加载数据库完成");
}
public void start(){
String input = null;
while(true){
System.out.println("=================================");
System.out.println("一、菜单:");
System.out.println("=================================");
System.out.println("1. 测试任务一:获取两个节点之间两跳以内的所有可达路径");
System.out.println("2. 测试任务二:节点层数穿透式查询");
System.out.println("3. 测试任务三:判断两个节点之间是否存在环路");
System.out.println("=================================");
System.out.print("请输入任务对应数字:");
String num=scanner.nextLine();
switch(num){
case "1":
System.out.println("请输入两个公司的名称[name1(String) name2(String)]:");
input = scanner.nextLine();
String[] EnterName = input.split(" ");
taskStrategy = new Task1();
System.out.println("=================================");
System.out.println("查询结果为:");
taskStrategy.RunTask(EnterName[0],EnterName[1], gc);
System.out.println("=================================");
//System.out.println(EnterName[0]+" "+EnterName[1]);
break;
case "2":
System.out.println("请输入公司名称和要查询的层数[name(String) layers(int)]:");
input = scanner.nextLine();
String EnterpriseName = input.split(" ")[0];
String Layer = input.split(" ")[1];
System.out.println(EnterpriseName+" "+ Layer);
taskStrategy = new Task2();
System.out.println("=================================");
System.out.println("查询结果为:");
taskStrategy.RunTask(EnterpriseName,Layer, gc);
System.out.println("=================================");
break;
case "3":
System.out.println("请输入要测试环路的两个公司的名称[name1(String) name2(String)]:");
input = scanner.nextLine();
String[] EnterName_huang = input.split(" ");
taskStrategy = new Task3();
System.out.println("=================================");
System.out.println("查询结果为:");
taskStrategy.RunTask(EnterName_huang[0],EnterName_huang[1], gc);
System.out.println("=================================");
break;
default:
System.out.println("没有该选项,请输入正确数字选项!!");
break;
}
System.out.println("按回车键继续....");
String temp = scanner.nextLine();
}
}
}
public interface TaskStrategy {
void RunTask(String arg1,String arg2,GstoreConnector gc);
String GetSQL(String arg1,String arg2,int val);
void ShowResult(String arg1,String arg2,String result,int val);
}
public class Task1 implements TaskStrategy{
boolean isempty = true;
@Override
public void RunTask(String arg1, String arg2, GstoreConnector gc) {
String res=null;
// TODO Auto-generated method stub
//one
String sparql1 = GetSQL(arg1, arg2, 1);
//test
// System.out.println("sql语句为:"+sparql1);
// query
res = gc.query("jinrong", "json", sparql1);
//show
ShowResult(arg1, arg2, res, 1);
//two
String sparql2 = GetSQL(arg1, arg2, 2);
//test
// System.out.println("sql语句为:"+sparql2);
// query
res = gc.query("jinrong", "json", sparql2);
//show
ShowResult(arg1, arg2, res, 2);
//three
String sparql3 = GetSQL(arg1, arg2, 3);
//test
// System.out.println("sql语句为:"+sparql3);
// query
res = gc.query("jinrong", "json", sparql3);
//show
ShowResult(arg1, arg2, res, 3);
//four
String sparql4 = GetSQL(arg1, arg2, 4);
//test
// System.out.println("sql语句为:"+sparql4);
// query
res = gc.query("jinrong", "json", sparql4);
//show
ShowResult(arg1, arg2, res, 4);
//last note:
if(isempty) System.out.println("两个公司之间两跳内不存在可达路径!!");
}
@Override
public String GetSQL(String arg1, String arg2,int val) {
String sparql = "PREFIX : <file:///F:/d2r-server-0.7/holder8.nt#holder_copy/>\nSELECT DISTINCT";
if(val==1){
sparql += " ?x " + "where"
+ "{"
+ " :"+arg1+ " ?x" + " :"+arg2+ ". "
+ "}";
}
else if(val ==2){
sparql += " ?x " + "where"
+ "{"
+ " :"+arg2+ " ?x" + " :"+arg1+ ". "
+ "}";
}
else if(val == 3){
sparql += " ?x " + "where"
+ "{"
+ " ?x ?b" +" :"+ arg2 + ". \n"
+ " :"+arg1+" ?c ?x."
+ "}";
}
else if(val == 4){
sparql += " ?x " + "where"
+ "{"
+ " ?x ?b" +" :"+ arg1 + ". \n"
+ " :"+arg2+" ?c ?x."
+ "}";
}
return sparql;
}
@Override
public void ShowResult(String arg1,String arg2,String result,int val) {
//1.将json字符串转化为json对象
JSONObject json = JSONObject.parseObject(result);
int AnsNum = json.getIntValue("AnsNum");
String Result_x = null;
if(AnsNum>=1){
//第二层
JSONObject bindingsjson = json.getJSONObject("results");
//第三层
JSONArray bindingsarrys = bindingsjson.getJSONArray("bindings");
//链式编程直接得到结果
Result_x = ((JSONObject)bindingsarrys.get(0)).
getJSONObject("x").getString("value");
}
// TODO Auto-generated method stub
if(val==1){
if(AnsNum>=1&&Result_x.equals("http://localhost:2020/vocab/resource/holder_copy_holder_name")){
System.out.println("一跳:" + arg1+ " --> " + arg2);
isempty = false;
}
}
else if(val ==2){
if(AnsNum>=1&&Result_x.equals("http://localhost:2020/vocab/resource/holder_copy_holder_name")){
System.out.println("一跳:" + arg2 + " --> " + arg1);
isempty = false;
}
}
else if(val == 3){
if(AnsNum>=1&&Result_x.contains("file:///F:/d2r-server-0.7/holder8.nt#holder_copy/")){
// file:///F:/d2r-server-0.7/holder8.nt#holder_copy/
String ShowAnsString = Result_x.substring(Result_x.lastIndexOf("/")+1);
System.out.println("两跳:" + arg1+ " --> " + ShowAnsString +" --> "+ arg2);
isempty = false;
}
}
else if(val == 4){
if(AnsNum>=1&&Result_x.contains("file:///F:/d2r-server-0.7/holder8.nt#holder_copy/")){
// file:///F:/d2r-server-0.7/holder8.nt#holder_copy/
String ShowAnsString = Result_x.substring(Result_x.lastIndexOf("/")+1);
System.out.println("两跳:" + arg2+ " --> " + ShowAnsString +" --> "+ arg1);
isempty = false;
}
}
}
}
public class Task2 implements TaskStrategy {
@Override
public void RunTask(String arg1, String arg2, GstoreConnector gc) {
// TODO Auto-generated method stub
//一层一层计算
// for(int i=1;i<=Integer.parseInt(arg2);i++){
// }
String res;
String sparql = GetSQL(arg1, arg2, 0);
res = gc.query("jinrong", "json", sparql);
// test
System.out.println("sql语句为:"+sparql);
ShowResult(arg1, arg2, res, 0);
}
@Override
public String GetSQL(String arg1, String arg2, int val) {
// TODO Auto-generated method stub
String sparql = "PREFIX : <file:///F:/d2r-server-0.7/holder8.nt#holder_copy/>\nSELECT DISTINCT ";
sparql += "(kHopReachablePath(?x, :"+ arg1+", true, "+arg2+", {}) AS ?y)" + " where{ }";
return sparql;
}
@Override
public void ShowResult(String arg1, String arg2, String result, int val) {
// TODO Auto-generated method stub
System.out.println("查询结果为:");
System.out.println(result);
}
}
public class Task3 implements TaskStrategy{
@Override
public void RunTask(String arg1, String arg2, GstoreConnector gc) {
// TODO Auto-generated method stub
String res;
String sparql = GetSQL(arg1, arg2, 0);
res = gc.query("jinrong", "json", sparql);
// test
// System.out.println("sql语句为:"+sparql);
ShowResult(arg1, arg2, res, 0);
}
@Override
public String GetSQL(String arg1, String arg2, int val) {
// TODO Auto-generated method stub
String sparql = "PREFIX : <file:///F:/d2r-server-0.7/holder8.nt#holder_copy/>\nSELECT ";
sparql += "(cycleBoolean(:" + arg1 + ",:"+ arg2 + ",true,{}) as ?x) " + "where{ }";
return sparql;
}
@Override
public void ShowResult(String arg1, String arg2, String result, int val) {
// TODO Auto-generated method stub
//1.将json字符串转化为json对象
JSONObject json = JSONObject.parseObject(result);
int AnsNum = json.getIntValue("AnsNum");
String Result_x = null;
if(AnsNum>=1){
//第二层
JSONObject bindingsjson = json.getJSONObject("results");
//第三层
JSONArray bindingsarrys = bindingsjson.getJSONArray("bindings");
//链式编程直接得到结果
Result_x = ((JSONObject)bindingsarrys.get(0)).
getJSONObject("x").getString("value");
}
if(Result_x.equals("true")){
System.out.println("公司:"+arg1+" 和 公司:"+arg2+ " 存在环形持股。。。");
}else{
System.out.println("公司:"+arg1+" 和 公司:"+arg2+ " 不存在环形持股。。。");
}
}
}