一、导入csv 数据,
1、网上下载 航班数据 https://download.csdn.net/download/w690333243/12026892
2、本地安装Arangodb https://download.csdn.net/download/w690333243/12026899
3、环境变量配置 arangodb安装目录下的 bin路径
C:\Program Files\ArangoDB3 3.5.3\usr\bin
如果不配做环境变量,和jdk一样,cmd模式下要进入 C:\Program Files\ArangoDB3 3.5.3\usr\bin 目录下才可执行命令
arangoimp --file E:\arangodb\airports.csv --collection airports --create-collection true --type csv
arangoimp --file E:\arangodb\flights.csv --collection flights --create-collection true --type csv --create-collection-type edge
这里创建的是edge collection,为每一行创建一个edge,同时自动创建一个edge index方便快速查询(_from和_to组成了这样的index.).在csv中有两个特殊的列_from 和_to,它们的值为airports collection中的id,指明了从一个机场飞往另外一个机场。
注意:上面的命令直接使用了 _system数据库,如果你想导入到自定义数据库(如atest数据库), 新建数据库 atest,然后使用如下命令
arangoimp --file E:\arangodb\airports.csv --server.database atest --create-database true --collection airports --create-collection true --type csv
arangoimp --file E:\arangodb\flights.csv --server.database atest --create-database true --collection flights --create-collection true --type csv --create-collection-type edge
注:是cmd 窗口中导入,不是 arangodb shell 窗口导入
写于2019年12月11日
二、ArangoDB程序介绍
1、arangod
它是ArangoDB数据库的守护程序,运行后就是ArangoDB数据库服务器的守护进程。
2、arangosh
ArangoDB的Shell环境。
3、arangoimp
ArangoDB数据库导入工具
4、arangodump
ArangoDB数据库的备份工具
5、arangorestore
ArangoDB数据库的恢复工具
6、foxx-manager
一个Shell脚本,管理Foxx应用程序
7、arango-dfdb
ArangoDB的数据文件调试器
8、arangob
ArangoDB的测试和评分工具,主要用于ArangoDB的开发和测试。
三、java 操作数据库
1、pom.xml中 maven依赖
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>arangodb-java-driver</artifactId>
<version>6.4.1</version>
</dependency>
2、代码
import java.util.Map;
import com.arangodb.ArangoCollection;
import com.arangodb.ArangoCursor;
import com.arangodb.ArangoDB;
import com.arangodb.ArangoDBException;
import com.arangodb.ArangoDatabase;
import com.arangodb.entity.BaseDocument;
import com.arangodb.util.MapBuilder;
/**
* @author wangqx
*
*/
public class ArangodbTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 配置和打开连接以启动ArangoDB
ArangoDB arangoDB = new ArangoDB.Builder().host("127.0.0.1", 8529).user("root").password("123456").build();
try {
// 创建数据库
String dbName = "TestDbb";
ArangoDatabase mydb = arangoDB.db(dbName); 获取数据库实例
// System.out.println("mydb:"+mydb);
if (!mydb.exists()) { 如果数据库不存在
arangoDB.createDatabase(dbName); 创建数据库
mydb.create();//或者使用这个方法
}
// 创建Collection集合
String collectionName = "TestCollection";
ArangoCollection myArangoCollection = arangoDB.db(dbName).collection(collectionName); 获取集合实例
if (!myArangoCollection.exists()) { 如果集合不存在
arangoDB.db(dbName).createCollection(collectionName); 创建集合
myArangoCollection.create();//或者使用这个方法
}
// 创建document文档
BaseDocument myObject = new BaseDocument();
//myObject.setKey("myKey"); 设置每行数据的主键,可以不用设置;如果设置,则要保证唯一性
myObject.addAttribute("name", "张三");
myObject.addAttribute("age", 42);
arangoDB.db(dbName).collection(collectionName).insertDocument(myObject);
// 查询document文档
BaseDocument myDocument = arangoDB.db(dbName).collection(collectionName).getDocument("myKey",
BaseDocument.class);
System.out.println("Key: " + myDocument.getKey());
System.out.println("Attribute name: " + myDocument.getAttribute("name"));
System.out.println("Attribute age: " + myDocument.getAttribute("age"));
// 更新document文档
myObject.addAttribute("sex", "男");
arangoDB.db(dbName).collection(collectionName).updateDocument("myKey", myObject);
// 删除document文档
// arangoDB.db(dbName).collection(collectionName).deleteDocument("myKey");
String query = "FOR t IN TestCollection FILTER t.name == @name "
+ "REMOVE t IN TestCollection LET removed = OLD RETURN removed";
Map<String, Object> bindVars = new MapBuilder().put("name", "张三").get();
//清除集合中 张三的 数据
ArangoCursor<BaseDocument> cursor = arangoDB.db(dbName).query(query, bindVars, null, BaseDocument.class);
// cursor.forEachRemaining(aDocument -> {
// System.out.println("Removed document " + aDocument.getKey());
// });
} catch (ArangoDBException e) {
e.printStackTrace();
}
}
}
更新于 2019年12月12日 16:39
参考
https://blog.csdn.net/u011119840/article/details/87856235 windows10下给arangodb导入csv数据文件
https://blog.csdn.net/chszs/article/details/20369433 ArangoDB数据库入门
https://blog.csdn.net/u011311291/article/details/86632594 ArangoDB教程(三)-使用java操作ArangoDB
https://blog.csdn.net/rensihui/article/details/78804706 ArangoDB入门教程(四)java操作ArangoDB数据库
https://www.cnblogs.com/minglex/p/9383849.html ArangoDB简单实例介绍 航班数据实例
https://blog.csdn.net/weixin_43363871/article/details/93460105 ArangoDB(三)——简单实例
http://www.it1352.com/OnLineTutorial/arangodb/arangodb_aql_example_queries.html ArangoDB - AQL示例查询
https://blog.csdn.net/u011311291/article/details/86628815 ArangoDB教程(二)-AQL语句使用,图使用,结合WEB界面端
https://blog.csdn.net/a499477783/article/details/79177307 ArangoDB数据导入
https://www.cnblogs.com/minglex/p/9705481.html ArangoDB数据导入
ArangoDB 的graph查询
3、如果要创建Edge类型的集合,即关系图。使用CollectionCreateOptions
// 集合
ArangoCollection coll = db.collection("QidianBooks");
if (!coll.exists()) {
CollectionCreateOptions cco = new CollectionCreateOptions();
cco.type(CollectionType.EDGES);
db.createCollection("QidianBooks", cco);
}
参考:https://blog.csdn.net/justlpf/article/details/89497099 neo4j数据库导入到arangodb
四、图 两顶点间的最短路径查询
public static void edgeTest() {
// TODO Auto-generated method stub
// 配置和打开连接以启动ArangoDB
ArangoDB arangoDB = new ArangoDB.Builder().host("127.0.0.1", 8529).user("root").password("123456..xu").build();
Set<BaseDocument> baseSet = new HashSet();
List<BaseDocument> baseList = new ArrayList();
try {
// 创建数据库
String dbName = "TestDbb";
ArangoDatabase mydb = arangoDB.db(dbName);
// System.out.println("mydb:"+mydb);
mydb.drop();
if (!mydb.exists()) {
arangoDB.createDatabase(dbName);
}
// 创建Collection集合
String collectionName = "User";
ArangoCollection myArangoCollection = arangoDB.db(dbName).collection(collectionName);
if (!myArangoCollection.exists()) {
arangoDB.db(dbName).createCollection(collectionName);
// myArangoCollection.create();
}
// 创建document文档
for(int i=0;i<100;i++) {
BaseDocument myObject = new BaseDocument();
myObject.addAttribute("name", ToolUtils.getUserRandomName());
myObject.addAttribute("age", ToolUtils.getRandomNum(18, 39));
DocumentCreateEntity dEntity = myArangoCollection.insertDocument(myObject);
dEntity.getId();
baseSet.add(myObject);
baseList.add(myObject);
//System.out.println("myObject.getId():"+myObject.getId());
//System.out.println("dEntity.getId():"+dEntity.getId());
}
/*
BaseDocument myObject2 = new BaseDocument();
myObject2.addAttribute("name", "李四");
myObject2.addAttribute("age", 32);
DocumentCreateEntity dEntity2 = myArangoCollection.insertDocument(myObject2);
dEntity2.getId();
baseSet.add(myObject2);
baseList.add(myObject2);
BaseDocument myObject3 = new BaseDocument();
myObject3.addAttribute("name", "王五");
myObject3.addAttribute("age", 34);
DocumentCreateEntity dEntity3 = myArangoCollection.insertDocument(myObject3);
dEntity3.getId();
baseSet.add(myObject3);
baseList.add(myObject3);
BaseDocument myObject4 = new BaseDocument();
myObject4.addAttribute("name", "李丽");
myObject4.addAttribute("age", 22);
DocumentCreateEntity dEntity4 = myArangoCollection.insertDocument(myObject4);
dEntity4.getId();
baseSet.add(myObject4);
baseList.add(myObject4);
BaseDocument myObject5 = new BaseDocument();
myObject5.addAttribute("name", "张靓颖");
myObject5.addAttribute("age", 31);
DocumentCreateEntity dEntity5 = myArangoCollection.insertDocument(myObject5);
dEntity5.getId();
baseSet.add(myObject5);
baseList.add(myObject5);
BaseDocument myObject6 = new BaseDocument();
myObject6.addAttribute("name", "王力宏");
myObject6.addAttribute("age", 42);
DocumentCreateEntity dEntity6 = myArangoCollection.insertDocument(myObject6);
dEntity6.getId();
baseSet.add(myObject6);
baseList.add(myObject6);
*/
// 集合
ArangoCollection coll = mydb.collection("RelationShip");
if (!coll.exists()) {
CollectionCreateOptions cco = new CollectionCreateOptions();
cco.type(CollectionType.EDGES);
mydb.createCollection("RelationShip", cco);
}
int count = 100;//baseList.size() * (baseList.size() -1)/2;
for(int i = 0;i< count;i++) {
int fromRandom = (int)(Math.random() * (baseList.size() - 1 ) + 1);
BaseDocument fromBd = baseList.get(fromRandom);
BaseEdgeDocument baseEdgeDocument = new BaseEdgeDocument();
baseEdgeDocument.setFrom(fromBd.getId());
int toRandom = (int)(Math.random() * (baseList.size() - 1 ) + 1);
System.out.println("fromRandom:"+fromRandom+" toRandom:"+toRandom);
System.out.println("i========="+i);
if(toRandom == fromRandom) {
System.err.println("i========="+i);
System.err.println("相等");
}else {
System.out.println("不相等");
}
while(toRandom == fromRandom) {
System.err.println("需要循环");
toRandom = (int)(Math.random() * (baseList.size() - 1 ) + 1);
System.err.println("After fromRandom:"+fromRandom+" toRandom:"+toRandom);
}
System.out.println("i========="+i);
BaseDocument toBd = baseList.get(toRandom);
baseEdgeDocument.setTo(toBd.getId());
System.out.println("insert fromBd.getId():"+fromBd.getId()+" toBd.getId():"+toBd.getId());
coll.insertDocument(baseEdgeDocument);
}
//String quer = "FOR p IN ANY SHORTEST_PATH @fromId TO @toId RelationShip return p";
String quer = "FOR p IN ANY SHORTEST_PATH @fromId TO @toId RelationShip return p";//最短路径问题,ANY 表示任意方向 关键字,SHORTEST_PATH为最短路径 关键字
Map<String, Object> bindVar = new MapBuilder()
.put("fromId", baseList.get(8).getId())
.put("toId", baseList.get(2).getId())
.get();
ArangoCursor<BaseDocument> curso = arangoDB.db(dbName).query(quer, bindVar, null, BaseDocument.class);
curso.forEachRemaining(aDocumen -> {
System.out.println("名称: " + aDocumen.getAttribute("name"));
});
// 查询document文档
BaseDocument myDocument = arangoDB.db(dbName).collection(collectionName).getDocument("myKey",
BaseDocument.class);
// 更新document文档
//myObject.addAttribute("sex", "男");
//arangoDB.db(dbName).collection(collectionName).updateDocument("myKey", myObject);
// 删除document文档
// arangoDB.db(dbName).collection(collectionName).deleteDocument("myKey");
String query = "FOR t IN TestCollection FILTER t.name == @name "
+ "REMOVE t IN TestCollection LET removed = OLD RETURN removed";
Map<String, Object> bindVars = new MapBuilder().put("name", "张三").get();
// 清除 张三的 数据
// ArangoCursor<BaseDocument> cursor = arangoDB.db(dbName).query(query, bindVars, null, BaseDocument.class);
// cursor.forEachRemaining(aDocument -> {
// System.out.println("Removed document " + aDocument.getKey());
// });
} catch (ArangoDBException e) {
e.printStackTrace();
}
}
https://blog.csdn.net/Missbelover/article/details/103228294 ArangoDB 中的Graph
https://blog.csdn.net/yuzongtao/article/details/76061897 ArangoDB AQL中的图形绘制遍历
https://blog.csdn.net/Missbelover/article/details/103228294 ArangoDB 中的Graph
https://cloud.tencent.com/developer/ask/199611 ArangoDB:图遍历中的顺序
https://blog.csdn.net/xugc2015/article/details/100043751 ArangoDb学习笔记————AQL tutorial(四)
https://blog.csdn.net/xugc2015/article/details/100042396 ArangoDb学习笔记————AQL tutorial(二)
https://blog.csdn.net/gxq926/article/details/90239682Arangodb最短路径查询语法
https://www.cnblogs.com/litufu/articles/9651149.html ArangoDB 学习笔记 (4)graph 航班信息方面的查询
五、AQL 语句解释
FOR v IN 1..100 INBOUND "User/669287" RelationShip RETURN v
1..100表示遍历的最小深度为1、最大深度为100, IN min..max 为固定写法,固定语法
更新于 2019年12月17日 12:46
2、 graph数据查询
FOR vertex[, edge[, path]]
IN [min[..max]]
OUTBOUND|INBOUND|ANY startVertex
edgeCollection[, more…]
解释:
FOR 有三个参数
‣ vertex (object): 遍历中的当前顶点
‣ edge (object, optional): 遍历中的当前边
‣ path (object, optional): 两个对象的路径表示
‣ vertices: 此路径上所有顶点的数组
‣ edges: 此路径上所有边的数组
IN min…max: 定义遍历的最小深度和最大深度。如果未指定,默认为1!
OUTBOUND/INBOUND/ANY :定义搜索的方向
edgeCollection: 保存在遍历中要考虑的边缘的集合的一个或多个名称
OPTIONS options(object,optional):用于修改遍历的执行。只有以下属性有效果,所有其他属性将被忽略:
uniqueVertices(string):可选地确保顶点唯一性
“path” - 保证没有路径返回一个重复的顶点
“global” - 保证在遍历期间每个顶点最多被访问一次,无论从起始顶点到这个顶点有多少路径。如果您从最小深度min depth > 1之前发现的顶点开始,可能根本不会返回(它仍然可能是路径的一部分)。注意: 使用此配置,结果不再是确定性的。如果从startVertex到顶点有多条路径,则选择其中一条路径。
“none”(默认) - 不对顶点应用唯一性检查
uniqueEdges(string):可选地确保边缘唯一性
“path”(默认) - 保证没有路径返回一个重复的边
“global” - 保证在遍历过程中,每个边缘最多被访问一次,无论从起始顶点到该边缘有多少条路径。如果从a开始,min depth > 1在最小深度之前发现的边缘根本不会被返回(它仍然可能是路径的一部分)。注意: 使用此配置,结果不再是确定性的。如果有从多个路径startVertex超过边缘的那些中的一个被拾取。
“none” - 不对边缘应用唯一性检查。注意: 使用此配置,遍历将跟随边沿周期。
bfs(bool):可选地使用可选的宽度优先遍历算法
true - 遍历将被执行宽度优先。结果将首先包含深度1的所有顶点。比深度2处的所有顶点等等。
false(默认) - 遍历将以深度优先执行。它首先将深度1的一个顶点的最小深度的最小深度返回到最大深度。对于深度1处的下一个顶点,依此类推。
查询示例:
查所洛杉矶可以直达的所有飞机场
FOR airport IN OUTBOUND 'airports/LAX' flights
RETURN DISTINCT airport
查所洛杉矶可以直达的所有飞机场,优化AQL语句:
FOR airport IN OUTBOUND 'airports/LAX' flights
OPTIONS {
bfs:true,
uniqueVertices:'global'}
RETURN airport
这个查询将比上面的使用distict快很多。因为distict是在遍历完所有节点后再去除重复的,而options则可以直接过掉重复的结果不进行遍历。
返回10个洛杉矶的航班和他们的目的地,如下AQL语句:
FOR airport, flight IN OUTBOUND 'airports/LAX' flights
LIMIT 10
RETURN {airport, flight}
3、 唯一遍历
对于最小深度大于2的遍历,有两个选项可以选择:
深度优先(默认):继续沿着从起始顶点到该路径上的最后顶点的边缘,或者直到达到最大遍历深度,然后向下走其他路径
广度优先(可选):从开始顶点到下一个级别遵循所有边缘,然后按另一个级别跟踪邻居的所有边缘,并继续这个模式,直到没有更多的边缘跟随或达到最大的遍历深度。
由于不同点之间的路径可能有多条,也可能存在闭环线路
默认情况下,遍历的时候如果path中遇到了相同的edge就会停止遍历;这将可以防止遍历存在绕圈情况,让遍历可以到达最底层节点。
在一个path上可能会出现重复的vertex,除非你明确声明不要重复的点。
示例
FOR v,e,p IN 1..5 OUTBOUND 'vertex/s' edgs
OPTIONS {
uniqueVertices:'none',
uniqueEdges:'path'
}
RETURN CONCAT_SEPARATOR('->',p.vertices[*]._key)
这个uniqueVertices:‘none’和uniqueEdges:‘path’都是默认设置,不设置也是一样。这样最开是的节点也可以是最后的节点,因为我们在设置的时候并没有要求path中有唯一的点。如果要设置为唯一的,可以也设置为‘path’,这样一条路径中的点也将变为唯一的。
global保证每个点在所有遍历中只出现一次。它仅适用于广度优先。示例
FOR v IN 1..5 OUTBOUND 'vertex/s' edgs
OPTIONS{
bfs:ture,
uniqueVertices:'global'
RETURN v._key
4、LET关键字
LET可以用来声明变量,来将查询结果赋值给变量。
FOR f IN flights
FILTER f._from == 'airports/BIS'
LIMIT 100
LET h = FLOOR(f.DepTime / 100)
LET m = f.DepTime % 100
RETURN {
year: f.Year,
month: f.Month,
day: f.DayofMonth,
time: f.DepTime,
iso: DATE_ISO8601(f.Year, f.Month, f.DayofMonth, h, m)
}
spring-data-demo中,edge涉及到from,to的,需要使用对象,不能是String,而查询参数需要使用String,这个需要注意
即:
@Edge
public class RelationOf {
@Id
private String id;
@From
private UserInfo fromUserInfo; //不能使用String类型
@To
private UserInfo toUserInfo;
}
@Query("FOR v IN ANY SHORTEST_PATH @fromId TO @toId relationOf return v")
List<UserInfo> getShortestPath(@Param("fromId") String fromId, @Param("toId") String toId);//查询时候需要使用String类型
ArangoDB 的graph查询
ArangoDB简单实例介绍
ArangoDB 学习笔记 (4)graph
AQL 基本语法&用法
ArangoDB查询语言(AQL) 基本语法&用法
ArangoDB查询语言(AQL) 基本语法&用法
https://www.arangodb.com/docs/stable/aql/data-queries.html
更新于2020年12月06日 10:04 未起床
组合查询:MERGE()
查询顶点元素实体与边中的元素组成的新实体
FOR v,e IN 1 OUTBOUND 'userinfo/23742927' relationOf
return MERGE(v,{relation:e.relation,show:e.show})
MERGE()方法组合的是实体(即括号中的参数需要是一个实体),v是实体,大括号{}可以形成一个新的实体,relation是e中的元素,但是需要为查询到的e.relation起一个新的名字(我起了相同的名字relation)
https://www.arangodb.com/why-arangodb/sql-aql-comparison/