新工作需要用到 arangodb,由于之前没有接触过,所以从头开始学,记录一下学习过程中的重点。
一. ArangoDB 安装
1. 下载地址
官网地址:https://www.arangodb.com/download/
2. 部署步骤
-
下载 rpm 安装包并安装
rpm -ivh arangodb3-3.10.6-1.0.x86_64.rpm -
修改配置文件
修改配置文件/etc/arangodb3/arangod.conf,将endpoint = tcp://127.0.0.1:8529中的127.0.0.1更改为主机ip -
设置 root 密码
arango-secure-installation
-
启动 arangoDB 服务
- service arangodb3 start #启动arangoDB - service arangodb3 stop #关闭arangoDB - service arangodb3 restart #重启arangoDB - service arangodb3 status # 查看arangoDB的状态
-
进入命令行模式
arangosh
二. ArangoDB 操作命令
1. 数据库操作
1)创建数据库
db._createDatabase("example");
2)切换数据库
db._useDatabase("example");
3)获取当前数据库名、ID 和地址
require("@arangodb").db._name();
require("@arangodb").db._id();
require("@arangodb").db._path();
4)删除数据库
db._dropDatabase("example")
5)列出所有数据库
db._databases();
2. 表操作
1)创建集合
db._create("users");
2)删除集合
db._drop("users");
3)列出所有集合
db._collections();
3. 数据操作 ( Shell )
1)添加数据
db.users.insert({
"_id":"user/1",
"_key":"123",
"name":"user1",
"age":23,
"interests":["game","music"]
})
批量新增:
db.users.insert([
{"date1"},
{"date2"},
...
{"dateN"}
])
2)修改数据
db.users.update(
{"_key": "123"},
{"age": 35}
);
3)删除数据
db.users.remove({"_key":"124"});
4)统计数据
db.users.count();
5)返回集合文档对象
-
返回所有文档
db.users.all().toArray();
-
返回指定数量文档
db.users.all().limit(2).toArray();
-
返回随机文档
db.users.any();
-
根据条件查询文档对象
db.users.byExample({ "name": "user1", "age":35 }).toArray();
-
返回查询结果中的第一个文档对象
db.users.firstExample("age", 35);
-
根据 _id 或 _key 查询文档对象
db.users.document({"_id":"users/123"}); db.users.document({"_key": "123"}); db.users.document(["123","124"]);
-
判断文档是否存在
db.users.exists("123");
-
按 _key 删除文档
db.users.removeByKeys(["123","124"]);
4. AQL 语法
1)插入单个对象
INSERT {
"name": "Ned",
"surname": "Stark",
"alive": true,
"age": 41,
"traits": ["A","H","C","N","P"]
} INTO test
2)批量插入对象
AQL不允许INSERT在单个查询中针对同一集合的多个操作。但是可以使用FOR循环体,插入多个文档。
LET data = [
{ "name": "Robert", "surname": "Baratheon", "alive": false, "traits": ["A","H","C"] },
{ "name": "Jaime", "surname": "Lannister", "alive": true, "age": 36, "traits": ["A","F","B"] },
{ "name": "Catelyn", "surname": "Stark", "alive": false, "age": 40, "traits": ["D","H","C"] },
{ "name": "Cersei", "surname": "Lannister", "alive": true, "age": 36, "traits": ["H","E","F"] },
{ "name": "Daenerys", "surname": "Targaryen", "alive": true, "age": 16, "traits": ["D","H","C"] },
{ "name": "Jorah", "surname": "Mormont", "alive": false, "traits": ["A","B","C","F"] },
{ "name": "Petyr", "surname": "Baelish", "alive": false, "traits": ["E","G","F"] },
{ "name": "Viserys", "surname": "Targaryen", "alive": false, "traits": ["O","L","N"] },
{ "name": "Jon", "surname": "Snow", "alive": true, "age": 16, "traits": ["A","B","C","F"] },
{ "name": "Sansa", "surname": "Stark", "alive": true, "age": 13, "traits": ["D","I","J"] },
{ "name": "Arya", "surname": "Stark", "alive": true, "age": 11, "traits": ["C","K","L"] },
{ "name": "Robb", "surname": "Stark", "alive": false, "traits": ["A","B","C","K"] },
{ "name": "Theon", "surname": "Greyjoy", "alive": true, "age": 16, "traits": ["E","R","K"] },
{ "name": "Bran", "surname": "Stark", "alive": true, "age": 10, "traits": ["L","J"] },
{ "name": "Joffrey", "surname": "Baratheon", "alive": false, "age": 19, "traits": ["I","L","O"] },
{ "name": "Sandor", "surname": "Clegane", "alive": true, "traits": ["A","P","K","F"] },
{ "name": "Tyrion", "surname": "Lannister", "alive": true, "age": 32, "traits": ["F","K","M","N"] },
{ "name": "Khal", "surname": "Drogo", "alive": false, "traits": ["A","C","O","P"] },
{ "name": "Tywin", "surname": "Lannister", "alive": false, "traits": ["O","M","H","F"] },
{ "name": "Davos", "surname": "Seaworth", "alive": true, "age": 49, "traits": ["C","K","P","F"] },
{ "name": "Samwell", "surname": "Tarly", "alive": true, "age": 17, "traits": ["C","L","I"] },
{ "name": "Stannis", "surname": "Baratheon", "alive": false, "traits": ["H","O","P","M"] },
{ "name": "Melisandre", "alive": true, "traits": ["G","E","H"] },
{ "name": "Margaery", "surname": "Tyrell", "alive": false, "traits": ["M","D","B"] },
{ "name": "Jeor", "surname": "Mormont", "alive": false, "traits": ["C","H","M","P"] },
{ "name": "Bronn", "alive": true, "traits": ["K","E","C"] },
{ "name": "Varys", "alive": true, "traits": ["M","F","N","E"] },
{ "name": "Shae", "alive": false, "traits": ["M","D","G"] },
{ "name": "Talisa", "surname": "Maegyr", "alive": false, "traits": ["D","C","B"] },
{ "name": "Gendry", "alive": false, "traits": ["K","C","A"] },
{ "name": "Ygritte", "alive": false, "traits": ["A","P","K"] },
{ "name": "Tormund", "surname": "Giantsbane", "alive": true, "traits": ["C","P","A","I"] },
{ "name": "Gilly", "alive": true, "traits": ["L","J"] },
{ "name": "Brienne", "surname": "Tarth", "alive": true, "age": 32, "traits": ["P","C","A","K"] },
{ "name": "Ramsay", "surname": "Bolton", "alive": true, "traits": ["E","O","G","A"] },
{ "name": "Ellaria", "surname": "Sand", "alive": true, "traits": ["P","O","A","E"] },
{ "name": "Daario", "surname": "Naharis", "alive": true, "traits": ["K","P","A"] },
{ "name": "Missandei", "alive": true, "traits": ["D","L","C","M"] },
{ "name": "Tommen", "surname": "Baratheon", "alive": true, "traits": ["I","L","B"] },
{ "name": "Jaqen", "surname": "H'ghar", "alive": true, "traits": ["H","F","K"] },
{ "name": "Roose", "surname": "Bolton", "alive": true, "traits": ["H","E","F","A"] },
{ "name": "The High Sparrow", "alive": true, "traits": ["H","M","F","O"] }
]
FOR d IN data
INSERT d INTO test
3)检索集合中所有文档
FOR c IN test
RETURN c
4)检索指定文档
RETURN DOCUMENT("test","6377")
RETURN DOCUMENT("test",["6377","6378"])
5)更新文档
UPDATE "6377" WITH {alive:true} IN test
6)替换文档
REPLACE "6377" WITH {
name: "Ned",
surname: "Stark",
alive: false,
age: 41,
traits: ["A","H","C","N","P"]
} IN test
7)删除文档
REMOVE "6377" IN test
8)匹配文档
FILTER
查找满足比 _key 相等更复杂的文档,能够为要匹配的文档制定任意条件。
-
等于条件
FOR c IN test
FILTER c.name == "Ned"
RETURN c -
范围条件
FOR c IN test
FILTER c.age >= 13
RETURN c.name -
多种条件
FOR c IN test
FILTER c.age < 13
FILTER c.age != null
RETURN { name: c.name, age: c.age }//or
FOR c IN test
FILTER c.age < 13 AND c.age != null
RETURN { name: c.name, age: c.age } -
替代条件
FOR c IN test
FILTER c.name == "Jon" OR c.name == "Joffrey"
RETURN { name: c.name, surname: c.surname }
-模糊检索
FOR c IN test
FILTER c.name LIKE "%KE%"
RETURN c
或者
FOR c IN test
FILTER CONTAINS(c.name, "KE")
RETURN c
9)限制语法
LIMIT后面跟着一个最大显示数的数字,限制结果显示行数。
FOR c IN test
LIMIT 5
RETURN c.name
还可以使用LIMIT来跳过一定数量的记录返回下一个n个文档:
FOR c IN test
LIMIT 2, 5
RETURN c.name
10)排序语法
SORT()
DESC降序来反转排序顺序
FOR c IN test
SORT c.name DESC
LIMIT 10
RETURN c.name
11)去重
查询表中数据的所有字段并去重返回
FOR doc IN users
LET fields = ATTRIBUTES(doc)
FOR j IN fields
RETURN DISTINCT j
12)组长度计算
FOR u IN users
COLLECT WITH COUNT INTO length
RETURN length
13)统计表数据量
RETURN COUNT(IPAddress)
三. 图(Graph)
1. 示例
现在有3张表:owner、car和carGraph
分别记录车辆拥有人、车辆信息与两者之间的关系
1. 创建 owner 表和 car 表,并插入数据
INSERT {
"name": "John",
"userId": "123",
"carId": "456"
} INTO owner
INSERT {
"id": "456",
"carName": "Toyota Camry"
} INTO car
2. 创建 carGraph 表并记录 owner 表与 car 表之间的边信息
INSERT {
"_from": "A/A_document_id",
"_to": "B/B_document_id"
} INTO carGraph
3. 创建查询语句,可以根据 owner 表中的 name 查询出该用户拥有车辆的车名
FOR a IN owner
FILTER a.userId == "123" // 根据需要的条件过滤A表中的数据
LET b = (
FOR v, e, p IN 1..1 OUTBOUND a._id carGraph // 在C表中查找与A表关联的边
RETURN DOCUMENT(car, p.vertices[1]._id) // 获取边的_to顶点,即B表中的文档
)
RETURN b[0].carName // 返回B表中的carName字段
在AQL查询中,FOR v, e, p IN 1..1 OUTBOUND a._id C
这一行代码中的v
、e
和p
是用来定义变量的标识符。
v
:表示顶点(vertex),在这个查询中,它代表A表中的文档。e
:表示边(edge),在这个查询中,它代表C表中的边。p
:表示路径(path),在这个查询中,它代表从A表到B表的路径。
这个查询使用了OUTBOUND关键字,表示从A表的顶点出发,沿着C表中的边向外部(即B表)遍历。通过FOR v, e, p IN 1..1 OUTBOUND a._id C
这一行代码,我们定义了三个变量v
、e
和p
,用于在遍历过程中获取顶点、边和路径的信息。
v
用于获取当前遍历到的顶点的信息,可以通过v.fieldName
来访问顶点的字段。e
用于获取当前遍历到的边的信息,可以通过e.fieldName
来访问边的字段。p
用于获取当前遍历到的路径的信息,可以通过p.vertices
来访问路径上的顶点列表。
在这个查询中,我们只需要获取B表中的carName字段,所以并没有直接使用v
、e
和p
这些变量。但是,为了能够正确地遍历A表到B表的路径,我们需要在FOR
语句中定义这些变量。