本文内容来源于官网2019版的课程,运用美国机场航班实在数据,来构建图并写一些有趣的查询。
ArangoDB
官方对ArangoDB的介绍中,它是一个原生多模型
数据库
- 多模型:支撑3种主要的NoSQL数据模型,即key-value, documents, graph
- 原生:运用相同的底层中心和一套查询语言(即AQL)来支撑以上数据模型
ArangoDB的存储层级如下图所示
-
能够树立多个
Databases
,其间可包括恣意数量的collections
,安装好之后,有一个默许的数据库 _system -
Collections
能够包括恣意数量的documents
。ArangoDB中有两类型的collection
:document
collection和edge
collection -
Documents
中存储的都是JSON目标,这些JSON目标中会含有一些系统自带的特点,如 _key, _id, _rev, _from, _to
图根底
在ArangoDB中,每个边都有单一清晰的方向,假如两个点之间是双向的联系,则需要两个方向的边来表明。不过在图遍历时,你能够运用 ANY
来忽略边的方向(另外两种方向是 INBOUND
和OUTBOUND
)
ArangoDB答应你存储各种不同形状和体量的图,比方DAG有向无环图/有环/自环/多图(即两个极点之间有多个边)。
极点和边都是JSON document,所以说你能够存储恣意想存的信息。
数据集
案例中运用的数据集来自于美国超越3000个机场,30万个航班在2008年1月1日至1月15日期间的数据
其间airport
节点的结构如下,可看到每个机场包括全称,机场缩写,所在城市,州,经纬度,是否有VIP休息室等特点。
flights的结构如下,其间包括航班号,尾号,承运人编号,起飞下降时刻地点等信息。
以下是几个样例数据,会别离存储在airports和flights各自的collection中。
假如要形成图,能够把airports当成极点, flights当成边。airport中的 _id特点能够作为 flights中 _from和_to的值,从而表明某航班是从哪个机场飞到哪
最终对ArangoDB中的两类collection做个总结:
Document collections | Edge collections |
---|---|
包括document,每个document都是JSON目标 | 包括含有特殊边特点的document,即 _from和_to |
内置索引,每个document能够通过_key被快速检索到 | 每个edge collection都内置边索引 |
document可用作图中的极点,换句话说,假如不树立图,也能够作为普通document运用 | 相当于RDBMS中存储多对多联系的cross table |
下载和安装ArangoDB
之前的文章中已经介绍过了下载安装,一旦server发动后,能够通过在阅读器中拜访http://localhost:8529 来翻开web界面(ArangoDB社区把该UI界面称为 Aardvark)
本文仍然运用默许的 _system数据库为例
数据导入
从arangodb_demodata下载示例数据集,并解压得到两个.csv文件,别离是airports.csv和flights.csv
导入 Airports
运用导入东西arangoimport
,在指令行中键入指令来导入数据
arangoimport --file airports.csv的解压路径 --collection airports --create-collection true --type csv
能够运用–help来查看arangoimport协助:
arangoimport --help
假如运用的不是默许root用户,能够运用 –server.username name
来指定,假如没设置暗码或许取消了登录认证,则看到提示要输入暗码时直接回车。
解压后的airports.csv片段如下:
在指令行中敲入导入指令行,会看到相似如下的反应:
arangoimport在背面做了什么呢?
- 创建了一个新document collection,名叫 airports, 运用_key作为索引
- CSV文件中的每一行都树立一个document,除了首行和最终一行(为空行)
- csv的首行界说了特点名称
翻开web界面,左侧菜单栏挑选COLLECTIONS,能够看到airports,翻开后即可阅读刚才导入的数据,如下图:
导入 Flights
刚才导入的机场数据是图中的极点,现在咱们导入航班数据作为边来将极点衔接。
原始flights.csv数据如下, 该csv文件有超越28万行数据,一瞬间运用arangoimport导入时,会比airports.csv耗时:
由所以边数据,导入指令稍有不同,多了一个参数 --create-collection-type edge
:
arangoimport --file ~/Downloads/GraphCourse_DemoData_ArangoDB-2/flights.csv --collection flights --create-collection true --type csv --create-collection-type edge
键入导入指令后,会看到相似如下的显现:
这次,arangoimport在背面做了什么呢?
- 创建了一个新edge collection,名叫flights, 运用_key作为索引, _from和_to作为边索引。 由于csv文件中没有_key字段,所以ArangoDB会主动生成
- CSV文件中的每一行都树立一个edge document,除了首行和最终一行(为空行),其间_from和_to别离引用airports中的 _ids
能够想象,导入两批数据后,形成的图大概长这样:
翻开web界面,依然是从左侧菜单栏挑选COLLECTIONS,此刻会发现刚导入的flights,而且它的图标隐含了这是一个 edge collection.
AQL查询
数据安排妥当后,咱们能够运用ArangoDB的查询语言AQL来写一些查询了。
如上图,从web界面中挑选 QUERIES, 进入查询编辑页面来编写、履行和分析查询。这儿支撑语法高亮显现,还答应用户保存和办理查询。
动手实践
# 操练1,运用DOCUMENT()函数通过 _id 来找到John F. Kennedy机场
RETURN DOCUMENT("airports/JFK")
###########################################
# 操练2,运用FOR循环遍历airports, 运用_key过滤出 Kennedy机场,该模式会主动启用索引优化
FOR airport IN airports
FILTER airport._key == "JFK"
RETURN airport
###########################################
# 操练3,运用FILTER编写更复杂的过滤条件
FOR airport IN airports
FILTER airport.city == "New York"
AND airport.state == "NY"
RETURN airport
###########################################
操练4, 运用SORT和LIMIT语句排序并约束结果数量
FOR a IN airports
FILTER a.vip
SORT a.state, a.name DESC
LIMIT 5
RETURN a
###########################################
操练5, 不回来整个document,仅回来部分所需字段
FOR a IN airports
FILTER a._key IN ["JFK", "LAX"]
RETURN { fullName: a.name }
###########################################
操练6, 运用500个机场的经纬度通过GEO_POINT()来构建 GeoJSON目标
FOR a IN airports
LIMIT 500
RETURN GEO_POINT(a.long, a.lat)
###########################################
操练7, 回来collection中一切的文档数量
ArangoDB GraphCourse_Beginners Update 2
RETURN COUNT(airports)
###########################################
操练8, 回来一切提供VIP候机室的机场数量, 此例运用COLLECT完成
FOR airport IN airports
FILTER airport.vip
COLLECT WITH COUNT INTO count
RETURN count
图遍历 Graph Traversal
图数据库的长处是能够很高效地履行图遍历,即沿着某些边在图上进行游走,通过的边数量称为遍历深度,遍历起点S的深度为0;与S相邻的节点,他们的遍历深度为1, 如下图的A,B,C,同理,D,E,F的遍历深度为2
在正式履行图遍历前,咱们先来了解一下相关的查询语句语法:
留意:语法中的FOR,IN,ANY等都是大写,这只是一个实践常规,其实大小写无所谓。但变量名,特点,collection名都是要区别大小写的。
FOR之后最多跟三个变量,别离是,
- vertex (文档目标),当时被遍历的极点
- edge (文档目标,可选),当时被遍历的边
- path (文档目标,可选),用两个成员来代表当时的路径
- vertices, 一个极点数组,代表该路径上的一切极点
- edges, 一个边数组,代表该路径上的一切边
IN min..max:界说遍历的最小最大深度,min默许为1,max默许为min
startVertex: 遍历的起始点
OUTBOUND|INBOUND|ANY,这三个参数指定遍历时边的方向
-
OUTBOUND,沿着出方向
-
INBOUND,沿着入方向
-
ANY,沿着恣意方向
edgeCollection, edge collection的姓名,其间存有遍历时的边
动手实践
# 回来从洛杉矶机场LAX可直达(深度为1)的一切机场
FOR airport IN 1..1 OUTBOUND
"airports/LAX" flights
RETURN DISTINCT airport.name
# 找出从洛杉矶机场起飞的恣意10个目的地,回来格局为 {"airport": {机场目标}, "flight": {航班目标}}
FOR airport, flight IN OUTBOUND
'airports/LAX' flights
LIMIT 10
RETURN {airport, flight}
# 回来10个飞往俾斯麦机场BIS的航班号
FOR airport, flight IN INBOUND
"airports/BIS" flights
LIMIT 10
RETURN flight.FlightNum
# 查找1月5日至1月7日之间,从俾斯麦机场起飞或许下降的航班,回来对方机场所在城市跟到达时刻
FOR airport, flight IN ANY
'airports/BIS' flights
FILTER flight.Month == 1
AND flight.Day >= 5
AND flight.Day <= 7
RETURN { city: airport.city,
time: flight.ArrTimeUTC}
之前咱们学习过根底的AQL查询,假如跟遍历结合运用呢? 一起看几个比如:
# 仅运用根底的FOR循环查询,即看做是对collection中文档的查询
FOR flight IN flights
FILTER flight.TailNum == "N238JB"
RETURN flight
# 找出一切1月5日,FlightNum为860的航班,仅回来_from和_to特点
FOR flight IN flights
FILTER flight.FlightNum == 860
AND flight.Month == 1
AND flight.Day == 5
RETURN KEEP(flight, "_from", "_to")
# 等价于 RETURN {_from: flight._from, _to:flight._to}, 很显然KEEP写法更简练
# 找出一切FlightNum为859或860,在JFK机场起飞或下降的航班
# 办法1:直接用FOR循环文档过滤
FOR flight IN flights
FILTER flight.FlightNum IN [859, 860]
AND (flight._from == "airports/JFK" OR flight._to == "airports/JFK")
RETURN KEEP(flight, "_from", "_to", "FlightNum")
# 办法2: 用图遍历,长处是不只能够拜访flight信息,还能够拜访airport信息
FOR a, f IN ANY "airports/JFK" flights
FILTER f.FlightNum IN [859,860]
RETURN { airport: a.name, flight: f.FlightNum }
# 结合FOR循环跟图遍历, 从JFK和PBI两个机场一起作为起始点遍历,找出跟这两机场有关的编号为859或860的航班,以及对手机场的姓名和城市
FOR orig IN airports
FILTER orig._key IN ["JFK", "PBI"]
FOR dest, flight IN ANY orig flights
FILTER flight.FlightNum in [859, 860]
RETURN {A_airport: orig.name, B_airport: dest.name, B_city:dest.city, unique_flightnum:CONCAT(flight.UniqueCarrier, flight.FlightNum), day: flight.Day}
参考
[1]Graph Course for Freshers