ArangoDB

2022-04-08 00:00:00 查询 文档 节点 数组 关系

ArangoDB
一、ArangoDB 安装(CentOs7)
二、ArangoDB基本概念
三、ArangoDB基本使用
3.1、新增
3.2、删除
3.3、修改
3.4、 查询
3.5、for语句
3.6、limit的使用
3.7、filter的使用
3.8、排序语法
四、图查询
4.1、数据准备及生成图关系
4.2、查看关系图
4.3、从孩子找父母
4.4、从父母找孩子
4.5、爷爷找孙子
4.5、孙子找爷爷
五、地理位置
5.1、数据准备
5.2、发现附近的坐标
5.3、查找半径内的位置
六、嵌入特征
6.1、数据准备
6.2、解决特征
七、语法
运算符
for
return
FILTER
SORT
LIMIT
Let
COLLECT
组长计算
REMOVE
一、ArangoDB 安装(CentOs7)
1.下载安装包
https://www.arangodb.com/download/
2.安装arangodb
这边下载的Centos,rpm安装包
rpm -ivh arangodb3-3.9.0-1.0.x86_64.rpm
3.设置root密码
运行arango-secure-installation
4.为了能在局域网中访问WEB界面,修改配置文件/etc/arangodb3/arangod.conf
将endpoint = tcp://127.0.0.1:8529,默认端口为8529
更改为主机ip,例如endpoint = tcp://10.41.144.24:8529
5.开启arangoDB
systemctl start arangodb3.service
#systemctl stop arangodb3.service#关闭arangoDB
#systemctl restart arangodb3.service#重启arangoDB
6.查看arangoDB运行状态
systemctl status arangodb3.service ,出现active为正常运行

Configuration file:
/etc/arangodb3/arangod.conf
Start ArangoDB shell client:
> /usr/bin/arangosh
Start ArangoDB service:
> systemctl start arangodb3.service
Enable ArangoDB service:
> systemctl enable arangodb3.service

二、ArangoDB基本概念
AQL:arangodb的查询语言,可与类似于SQL。
Collections:分成Docunment和Edge两种类型,分别储存文档和边的信息
Document:可以储存一条记录,每一条类似于一个neo4j的节点
Edge:可以储存一条记录,与document不同,edge储存的是节点之间的关系(带有_from和_to)
graph:根据指定的一个或多个document和edge进行结合,组成一个graph
View:视图、对collections中的文档建立视图,已用来提供arangosearch的查询

三、ArangoDB基本使用
3.1、新增
语法是 INSERT document INTO collectionName。document是一个对象,它由属性键和值对组成。
属性键周围的引号在AQL中是可选的。
键总是字符序列(字符串),
属性值可以有不同的类型
INSERT {
"name": "Ned",
"surname": "Stark",
"alive": true,
"age": 41,
"traits": ["A","H","C","N","P"]
} INTO Characters

_id:Characters/1539
_rev:_duTGg8K---
_key:1539


_id则为表名和key的结合,_key为数据文档中这一条数据的键,_rev为系统管理的版本(revision id)

数据类型


布尔(真、假)
数(整数和浮点数)
字符串
数组
对象

3.2、删除
根据key对文档中相应的一条数据进行删除
REMOVE "1539" IN Characters

3.3、修改
update "1539" with { "name": "NedUpdate" } in Characters

replace的使用
用replace字段的话会将原来的数据删除掉,将新的填充进去,而不是只替换输入的参数
replace "1539" with{ "_key": "1539", "_id": "Characters/1539", "name": "NedRepalce", "id": "9f8a12152a844671aa9c9c7021303fcc", "sample": "弦酿坭苛忒蜩铬难怩遇汗昂浩筷烯母浑伫娠甄咀展郏帘岣晾拐捂妊幢胫镝蟓酉杓圻藤缱哑守陕锸焖桑狂写驹漾黯" } in Characters

3.4、 查询
根据id在文档内进行记录查找
return document ("Characters", "1966")

3.5、for语句
用for语句对文档内的所有文档进行遍历查询
for node in Characters return node

3.6、limit的使用
limit关键词要放在return前面
for node in Characters limit 1 return node

还可以使用LIMIT来跳过一定数量的记录返回下一个n个文档:
FOR c IN Characters
LIMIT 2, 5
RETURN c.name

3.7、filter的使用
filter作为aql语句中的筛选条件,和sql相同,放在句中
for node in Characters filter node.name == "Ned" return node
for node in Characters filter node.name =~"Ned" return node

当查询一条记录(一个节点)的时候,可以有一个或者多个筛选条件,这是可以用多个filter进行过滤
for node in Characters filter node._key=="2053" filter node.name=="Ned1" return node

也可以根据需要用and、or进行连接
for node in Characters filter node.name =="Ned1" and node._key =="2053" return node

范围查询
FOR c IN Characters
FILTER c.age >= 13
RETURN c.name

FOR c IN Characters
FILTER c.age > 13
FILTER c.age != null
RETURN { name: c.name, age: c.age }

FOR c IN Characters
FILTER c.name == "Ned" OR c.name == "Ned1"
RETURN { name: c.name, surname: c.surname }

3.8、排序语法
FOR c IN Characters
SORT c.name DESC
LIMIT 10
RETURN c.name

FOR c IN Characters
FILTER c.surname
SORT c.surname, c.name
LIMIT 10
RETURN {
surname: c.surname,
name: c.name
}

四、图查询
图查询是建立在collections中的节点文档(document)和关系文档(edge)之上。
一个图可以包含一个或多个节点文档和关系文档的组合。每一组关系文档需要声明起始节点所在文档和结束节点所在文档。
4.1、数据准备及生成图关系
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 Characters

生成图关系
LET data = [
{
"parent": { "name": "Ned", "surname": "Stark" },
"child": { "name": "Robb", "surname": "Stark" }
}, {
"parent": { "name": "Ned", "surname": "Stark" },
"child": { "name": "Sansa", "surname": "Stark" }
}, {
"parent": { "name": "Ned", "surname": "Stark" },
"child": { "name": "Arya", "surname": "Stark" }
}, {
"parent": { "name": "Ned", "surname": "Stark" },
"child": { "name": "Bran", "surname": "Stark" }
}, {
"parent": { "name": "Catelyn", "surname": "Stark" },
"child": { "name": "Robb", "surname": "Stark" }
}, {
"parent": { "name": "Catelyn", "surname": "Stark" },
"child": { "name": "Sansa", "surname": "Stark" }
}, {
"parent": { "name": "Catelyn", "surname": "Stark" },
"child": { "name": "Arya", "surname": "Stark" }
}, {
"parent": { "name": "Catelyn", "surname": "Stark" },
"child": { "name": "Bran", "surname": "Stark" }
}, {
"parent": { "name": "Ned", "surname": "Stark" },
"child": { "name": "Jon", "surname": "Snow" }
}, {
"parent": { "name": "Tywin", "surname": "Lannister" },
"child": { "name": "Jaime", "surname": "Lannister" }
}, {
"parent": { "name": "Tywin", "surname": "Lannister" },
"child": { "name": "Cersei", "surname": "Lannister" }
}, {
"parent": { "name": "Tywin", "surname": "Lannister" },
"child": { "name": "Tyrion", "surname": "Lannister" }
}, {
"parent": { "name": "Cersei", "surname": "Lannister" },
"child": { "name": "Joffrey", "surname": "Baratheon" }
}, {
"parent": { "name": "Jaime", "surname": "Lannister" },
"child": { "name": "Joffrey", "surname": "Baratheon" }
}
]

FOR rel in data
LET parentId = FIRST(
FOR c IN Characters
FILTER c.name == rel.parent.name
FILTER c.surname == rel.parent.surname
LIMIT 1
RETURN c._id
)
LET childId = FIRST(
FOR c IN Characters
FILTER c.name == rel.child.name
FILTER c.surname == rel.child.surname
LIMIT 1
RETURN c._id
)
FILTER parentId != null AND childId != null
//顶点和边相连
INSERT { _from: childId, _to: parentId } INTO ChildOf
RETURN NEW

新增单个图关系
孩子节点 --> 指向父节点
INSERT { _from: "Characters/9148", _to: "Characters/9139" } INTO ChildOf

4.2、查看关系图
FOR c IN ChildOf
RETURN c

但发现关系图的顶点都是用id表示,不易看清楚,可以使用以下语句查看
FOR c IN ChildOf
//CONCAT(c._from,DOCUMENT(c._from).name)
RETURN {_key:c._key,_id:c._id,_from:DOCUMENT(c._from).name,_to:DOCUMENT(c._to).name,_rev:c._rev}

4.3、从孩子找父母
FOR c IN Characters
FILTER c.name == "Bran"
//1..1分别表示小大遍历深度,OUTBOUND表示沿着边的方向,INBOUND表示反方向
FOR v IN 1..1 OUTBOUND c ChildOf
RETURN v.name

[
"Catelyn"
]

4.4、从父母找孩子
FOR c IN Characters
FILTER c.name == "Catelyn"
FOR v IN 1..1 INBOUND c ChildOf
RETURN v.name

[
"Robb",
"Sansa",
"Arya",
"Bran"
]

4.5、爷爷找孙子
FOR c IN Characters
FILTER c.name == "Tywin"
FOR v IN 2..2 INBOUND c ChildOf
RETURN v.name

--两条路径指向Joffrey
[
"Joffrey",
"Joffrey"
]

4.5、孙子找爷爷
FOR c IN Characters
FILTER c.name == "Joffrey"
FOR v IN 2..2 OUTBOUND c ChildOf
RETURN v.name

--两条路径指向Tywin
[
"Tywin",
"Tywin"
]

--去重
FOR c IN Characters
FILTER c.name == "Joffrey"
FOR v IN 2..2 OUTBOUND c ChildOf
RETURN DISTINCT v.name
[
"Tywin"
]

五、地理位置
5.1、数据准备
新建collection -Locations(doocument)
LET places = [
{ "name": "Dragonstone", "coordinate": [ 55.167801, -6.815096 ] },
{ "name": "King's Landing", "coordinate": [ 42.639752, 18.110189 ] },
{ "name": "The Red Keep", "coordinate": [ 35.896447, 14.446442 ] },
{ "name": "Yunkai", "coordinate": [ 31.046642, -7.129532 ] },
{ "name": "Astapor", "coordinate": [ 31.50974, -9.774249 ] },
{ "name": "Winterfell", "coordinate": [ 54.368321, -5.581312 ] },
{ "name": "Vaes Dothrak", "coordinate": [ 54.16776, -6.096125 ] },
{ "name": "Beyond the wall", "coordinate": [ 64.265473, -21.094093 ] }
]

FOR place IN places
INSERT place INTO Locations


5.2、发现附近的坐标
位置近的三个坐标
FOR loc IN Locations
LET distance = DISTANCE(loc.coordinate[0], loc.coordinate[1], 53.35, -6.25)
SORT distance
LIMIT 3
RETURN {
name: loc.name,
latitude: loc.coordinate[0],
longitude: loc.coordinate[1],
distance
}

[{
"name": "Vaes Dothrak",
"latitude": 54.16776,
"longitude": -6.096125,
"distance": 91491.58596795711
}, {
"name": "Winterfell",
"latitude": 54.368321,
"longitude": -5.581312,
"distance": 121425.66829502625
}, {
"name": "Dragonstone",
"latitude": 55.167801,
"longitude": -6.815096,
"distance": 205433.7784182078
}]

5.3、查找半径内的位置
200 公里 范围内
FOR loc IN Locations
LET distance = DISTANCE(loc.coordinate[0], loc.coordinate[1], 53.35, -6.25)
SORT distance
FILTER distance < 200 * 1000
RETURN {
name: loc.name,
latitude: loc.coordinate[0],
longitude: loc.coordinate[1],
distance: ROUND(distance / 1000)
}

[{
"name": "Vaes Dothrak",
"latitude": 54.16776,
"longitude": -6.096125,
"distance": 91
}, {
"name": "Winterfell",
"latitude": 54.368321,
"longitude": -5.581312,
"distance": 121
}]

六、嵌入特征
6.1、数据准备
LET data = [
{ "_key": "A", "en": "strong", "de": "stark" },
{ "_key": "B", "en": "polite", "de": "freundlich" },
{ "_key": "C", "en": "loyal", "de": "loyal" },
{ "_key": "D", "en": "beautiful", "de": "schön" },
{ "_key": "E", "en": "sneaky", "de": "hinterlistig" },
{ "_key": "F", "en": "experienced", "de": "erfahren" },
{ "_key": "G", "en": "corrupt", "de": "korrupt" },
{ "_key": "H", "en": "powerful", "de": "einflussreich" },
{ "_key": "I", "en": "naive", "de": "naiv" },
{ "_key": "J", "en": "unmarried", "de": "unverheiratet" },
{ "_key": "K", "en": "skillful", "de": "geschickt" },
{ "_key": "L", "en": "young", "de": "jung" },
{ "_key": "M", "en": "smart", "de": "klug" },
{ "_key": "N", "en": "rational", "de": "rational" },
{ "_key": "O", "en": "ruthless", "de": "skrupellos" },
{ "_key": "P", "en": "brave", "de": "mutig" },
{ "_key": "Q", "en": "mighty", "de": "mächtig" },
{ "_key": "R", "en": "weak", "de": "schwach" }
]
FOR d IN data
INSERT d INTO Traits

6.2、解决特征
仅返回每个字符的特征属性
FOR c IN Characters
RETURN c.traits

[
{ "traits": ["A","H","C","N","P"] },
{ "traits": ["D","H","C"] },
...
]

我们可以将特征数组与函数一起使用,以将元素用作文档键并在Traits集合DOCUMENT()中查找它们
FOR c IN Characters
RETURN DOCUMENT("Traits", c.traits)

[
[
{
"_key": "A",
"_id": "Traits/A",
"_rev": "_V5oRUS2---",
"en": "strong",
"de": "stark"
},
{
"_key": "H",
"_id": "Traits/H",
"_rev": "_V5oRUS6--E",
"en": "powerful",
"de": "einflussreich"
},
{
"_key": "C",
"_id": "Traits/C",
"_rev": "_V5oRUS6--_",
"en": "loyal",
"de": "loyal"
},
{
"_key": "N",
"_id": "Traits/N",
"_rev": "_V5oRUT---D",
"en": "rational",
"de": "rational"
},
{
"_key": "P",
"_id": "Traits/P",
"_rev": "_V5oRUTC---",
"en": "brave",
"de": "mutig"
}
],
[
{
"_key": "D",
"_id": "Traits/D",
"_rev": "_V5oRUS6--A",
"en": "beautiful",
"de": "schön"
},
{
"_key": "H",
"_id": "Traits/H",
"_rev": "_V5oRUS6--E",
"en": "powerful",
"de": "einflussreich"
},
{
"_key": "C",
"_id": "Traits/C",
"_rev": "_V5oRUS6--_",
"en": "loyal",
"de": "loyal"
}
],
...
]

只使用数组扩展表示法返回英文标签
FOR c IN Characters
RETURN DOCUMENT("Traits", c.traits)[*].en

[
[
"strong",
"powerful",
"loyal"
],
[
"strong",
"experienced",
"polite"
],
[
"beautiful",
"powerful",
"loyal"
],
...
]

合并角色和特征
我们将字母解析为有意义的特征!但我们也需要知道他们属于哪个角色。因此,我们需要合并字符文档和特征文档中的数据
FOR c IN Characters
RETURN MERGE(c, { traits: DOCUMENT("Traits", c.traits)[*].en } )

[
{
"_id": "Characters/9137",
"_key": "9137",
"_rev": "_duXChra---",
"alive": false,
"name": "Robert",
"surname": "Baratheon",
"traits": [
"strong",
"powerful",
"loyal"
]
},
{
"_id": "Characters/9138",
"_key": "9138",
"_rev": "_duXChra--_",
"age": 36,
"alive": true,
"name": "Jaime",
"surname": "Lannister",
"traits": [
"strong",
"experienced",
"polite"
]
},
...
]

七、语法
运算符
AND, &&(连词)
OR, ||(析取)
NOT, !(否定/反转)

==(平等的)
<=(小于或等于)
>=(大于或等于)
<(少于)
>(比...更棒)
!=(不等)
IN(包含在数组或范围中),也NOT IN
LIKE

for
有两个数组迭代:对数组的外部迭代 Characters加上对数组的内部迭代Locations
FOR u IN Characters
FOR l IN Locations
RETURN { "Characters" : u, "location" : l }

u1 i1
u2 i1
u3 i1

u1 i2
u2 i2
u3 i2

u1 i3
u2 i3
u3 i3

return
//返回完整文档
FOR u IN users
RETURN u

//返回每个文档的一个属性
FOR u IN users
RETURN u.name

//返回多个属性,可以这样构造一个对象
FOR u IN users
RETURN { name: u.name, age: u.age }

//还支持动态属性名称
FOR u IN users
RETURN { [ u._id ]: u.age }

FILTER
FOR u IN users
FILTER u.active == true && u.age < 39
RETURN u

FOR u IN users
FILTER u.active == true
FILTER u.age < 39
RETURN u

FOR u IN users
FILTER u.active == true
LIMIT 5
RETURN u

FOR u IN users
FILTER u.active == true
LIMIT 5
FILTER u.gender == "f"
RETURN u

FOR u IN users
FILTER u.active == true
SORT u.age ASC
LIMIT 5
FILTER u.gender == "f"
RETURN u

FOR u IN users
FILTER u.active == true AND u.gender == "f"
SORT u.age ASC
LIMIT 5
RETURN u

SORT
FOR u IN users
SORT u.lastName, u.firstName, u.id DESC
RETURN u

LIMIT
FOR u IN users
LIMIT 5
RETURN u

FOR u IN users
SORT u.firstName, u.lastName, u.id DESC
LIMIT 2, 5
RETURN u

Let
变量在 AQL 中是不可变的,这意味着它们不能被重新分配
下面的例子中,推荐数量的计算是使用一个LET语句分解出来的,从而避免了在语句中计算两次值RETURN
LET a = [1, 2, 3] // initial assignment

a = PUSH(a, 4) // syntax error, unexpected identifier
LET a = PUSH(a, 4) // parsing error, variable 'a' is assigned multiple times
LET b = PUSH(a, 4) // allowed, result: [1, 2, 3, 4]

FOR u IN users
LET numRecommendations = LENGTH(u.firstName)
RETURN {
"user" : u,
"numRecommendations" : numRecommendations,
"isPowerUser" : numRecommendations >= 10
}

另一个用例LET是在子查询中声明一个复杂的计算,使整个查询更具可读性
FOR u IN users
LET friends = (
FOR f IN friends
FILTER u.id == f.userId
RETURN f
)
LET memberships = (
FOR m IN memberships
FILTER u.id == m.userId
RETURN m
)
RETURN {
"user" : u,
"friends" : friends,
"numFriends" : LENGTH(friends),
"memberShips" : memberships
}

COLLECT
分组语法
FOR u IN users
COLLECT city = u.city
RETURN {
"city" : city
}

FOR u IN users
COLLECT city = u.city INTO groups
RETURN {
"city" : city,
"usersInCity" : groups
}

按city分组
[
{
"city": null,
"usersInCity": [
{
"u": {
"_key": "27676",
"_id": "users/27676",
"_rev": "_dw4b6qG---",
"firstName": "Anna",
"name": "Pavlova",
"profession": "artist"
}
},
{
"u": {
"_key": "PhilCarpenter",
"_id": "users/PhilCarpenter",
"_rev": "_dw4cYWK---",
"firstName": "Phil",
"name": "Carpenter",
"middleName": "G.",
"status": "inactive"
}
},
{
"u": {
"_key": "NatachaDeclerck",
"_id": "users/NatachaDeclerck",
"_rev": "_dw4cw0q---",
"firstName": "Natacha",
"name": "Declerck",
"location": "Antwerp"
}
}
]
},
{
"city": "Fortalezza",
"usersInCity": [
{
"u": {
"_key": "GilbertoGil",
"_id": "users/GilbertoGil",
"_rev": "_dw4cMf2---",
"firstName": "Gilberto",
"name": "Gil",
"city": "Fortalezza"
}
}
]
}
]

按领这个字段分组
FOR u IN users
COLLECT country = u.country, city = u.city INTO groups
RETURN {
"country" : country,
"city" : city,
"usersInCity" : groups
}

[
{
"country": null,
"city": null,
"usersInCity": [
{
"u": {
"_key": "27676",
"_id": "users/27676",
"_rev": "_dw4b6qG---",
"firstName": "Anna",
"name": "Pavlova",
"profession": "artist"
}
},
{
"u": {
"_key": "PhilCarpenter",
"_id": "users/PhilCarpenter",
"_rev": "_dw4cYWK---",
"firstName": "Phil",
"name": "Carpenter",
"middleName": "G.",
"status": "inactive"
}
},
{
"u": {
"_key": "NatachaDeclerck",
"_id": "users/NatachaDeclerck",
"_rev": "_dw4cw0q---",
"firstName": "Natacha",
"name": "Declerck",
"location": "Antwerp"
}
}
]
},
{
"country": null,
"city": "Fortalezza",
"usersInCity": [
{
"u": {
"_key": "GilbertoGil",
"_id": "users/GilbertoGil",
"_rev": "_dw4cMf2---",
"firstName": "Gilberto",
"name": "Gil",
"city": "Fortalezza"
}
}
]
}
]

FOR u IN users
COLLECT country = u.country, city = u.city INTO groups = u.name
RETURN {
"country" : country,
"city" : city,
"userNames" : groups
}
-------------------------
[
{
"country": null,
"city": null,
"userNames": [
"Pavlova",
"Carpenter",
"Declerck"
]
},
{
"country": null,
"city": "Fortalezza",
"userNames": [
"Gil"
]
}
]

FOR u IN users
COLLECT country = u.country, city = u.city INTO groups = {
"name" : u.name,
"isActive" : u.status == "active"
}
RETURN {
"country" : country,
"city" : city,
"usersInCity" : groups
}
//
[
{
"country": null,
"city": null,
"usersInCity": [
{
"name": "Pavlova",
"isActive": false
},
{
"name": "Carpenter",
"isActive": false
},
{
"name": "Declerck",
"isActive": false
}
]
},
{
"country": null,
"city": "Fortalezza",
"usersInCity": [
{
"name": "Gil",
"isActive": false
}
]
}
]

组长计算
FOR u IN users
COLLECT WITH COUNT INTO length
RETURN length

[
4
]

//等价
RETURN LENGTH(users)

REMOVE
FOR u IN users
REMOVE { _key: u._key } IN users

相关文章