数据函数
1.APPEND()
语法:APPEND(anyArray, values, unique) → newArray
Add all elements of an array to another array. All values are added at the end of the array (right side).
添加一个数组的所有元素到另外一个数组,将所有数据的元素添加到数组的尾部(即右边)
- anyArray (array): array with elements of arbitrary type 原数组
- values (array): array, whose elements shall be added to anyArray 需要添加的数据
- unique (bool, optional): if set to true, only those values will be added that are not already contained in anyArray. The default is false. 如果unique被设置为true,排除重复的数据
- returns newArray (array): the modified array
例子:
APPEND([ 1, 2, 3 ], [ 5, 6, 9 ])
// [ 1, 2, 3, 5, 6, 9 ]
APPEND([ 1, 2, 3 ], [ 3, 4, 5, 2, 9 ], true)
// [ 1, 2, 3, 4, 5, 9 ]
具体理解参考:https://docs.arangodb.com/3.3/AQL/Functions/Array.html
Array Operators (数组高级操作)
数组操作的参考:https://docs.arangodb.com/3.3/AQL/Advanced/ArrayOperators.html
1. Array expansion
为了比较容易的访问一个数组中的所有元素的被命名的属性。AQL提供了 [*]操作
使用 [*]操作作为一个元素,可以遍历在这个数组中的所有的元素。因此而可以访问每一个元素的特别的属性。
[*]操作的结果也是一个数组。
现有数组,有三个user信息
[
{
name: "john",
age: 35,
friends: [
{ name: "tina", age: 43 },
{ name: "helga", age: 52 },
{ name: "alfred", age: 34 }
]
},
{
name: "yves",
age: 24,
friends: [
{ name: "sergei", age: 27 },
{ name: "tiffany", age: 25 }
]
},
{
name: "sandra",
age: 40,
friends: [
{ name: "bob", age: 32 },
{ name: "elena", age: 48 }
]
}
]
问题:查询出每一个user的所有的朋友名字:
语句:
FOR u IN users
RETURN { name: u.name, friends: u.friends[*].name }
结果:
[ { "name" : "john", "friends" : [ "tina", "helga", "alfred" ] },
{ "name" : "yves", "friends" : [ "sergei", "tiffany" ] },
{ "name" : "sandra", "friends" : [ "bob", "elena" ] }
]
等效查询的语句为:
FOR u IN users
RETURN { name: u.name, friends: (FOR f IN u.friends RETURN f.name) }
2. Array contraction
为了展开嵌套数组中的结果。AQL提供了[**] 操作。 星号字符的数量表示数组嵌套的层数。
[**] 表示一级嵌套,等价于: FLATTEN(array)
或者FLATTEN(array, 1)
[***] 表示二级嵌套,等价于:FLATTEN(array, 2)
比较一下数据表达式 和 Array contraction操作
例如:下面的查询结果是每个user的朋友的数组
FOR u IN users
RETURN u.friends[*].name
结果为:
[
[
"tina",
"helga",
"alfred"
],
[
"sergei",
"tiffany"
],
[
"bob",
"elena"
]
]
如果目标是除去嵌套数组,我们可以在结果上使用 [**] 操作符,但是简单的把[**] 操作符加到查询中是不起作用的,因为u.friends 不是一个多维的嵌套数组,而是一个简单数组。
我们可以将上面的查询扩张一下,得到的是相同的结果
RETURN (
FOR u IN users RETURN u.friends[*].name
)
如果我们在查询结果上使用[**] 操作符
RETURN (
FOR u IN users RETURN u.friends[*].name
)[**]
查询结果就变成:
[
[
"tina",
"helga",
"alfred",
"sergei",
"tiffany",
"bob",
"elena"
]
]
注意:结果没有去重(de-duplicated), 为了去重复,可以在数组中使用 UNIQUE() 和 FLATTEN()
3 Inline expressions (内联表达式)
在循环数据的时候,为了过滤某个元素,限制返回的元素个数,需要使用当前元素。
内联表达式可以和 array expansion 和contraction 操作 [* ...], [** ...] 一起使用。
关键字:FILTER,LIMIT 和Return 需要遵守的语法要求是:
anyArray[* FILTER conditions LIMIT skip,limit RETURN projection]
嵌套数据 和 array Contraction的例子:
LET arr = [ [ 1, 2 ], 3, [ 4, 5 ], 6 ]
RETURN arr[** FILTER CURRENT % 2 == 0]
结果为所有的偶数被返回:
[
[ 2, 4, 6 ]
]
使用多个条件,limit和projection 复杂的比较大的查询是
FOR u IN users
RETURN {
name: u.name,
friends: u.friends[* FILTER CONTAINS(CURRENT.name, "a") AND CURRENT.age > 40
LIMIT 2
RETURN CONCAT(CURRENT.name, " is ", CURRENT.age)
]
}
返回名字中含有a,年龄大于40岁,不超过2个的friends
[
{
"name": "john",
"friends": [
"tina is 43",
"helga is 52"
]
},
{
"name": "sandra",
"friends": [
"elena is 48"
]
},
{
"name": "yves",
"friends": []
}
]
内联过滤(Inline filter)
场景:返回年龄大于自己的friends的名字,此时:inline FILTER 可以使用
语句:
FOR u IN users
RETURN { name: u.name, friends: u.friends[* FILTER CURRENT.age > u.age].name }
变量CURRENT可以使用访问当前数组的元素,FILTER条件可以引用CURRENT或外部作用域中有效的任何变量。(The FILTER condition can refer to CURRENT or any variables valid in the outer scope.)
lnline limit
LIMIT 限制了返回元素的个数 。LIMIT必须在FILTER之前在RETURN的后面。
FOR u IN users
RETURN { name: u.name, friends: u.friends[* LIMIT 1].name }
返回的结果为:
[
{ "name": "john", "friends": [ "tina" ] },
{ "name": "sandra", "friends": [ "bob" ] },
{ "name": "yves", "friends": [ "sergei" ] }
]
可以跳过某个或者某几个元素,直到第n个返回 ???(还在最多返回2个),例如:
FOR u IN users
RETURN { name: u.name, friends: u.friends[* LIMIT 1,2].name }
查询跳过第一个朋友,并且最多返回2个朋友,结果为:
[
{ "name": "john", "friends": [ "helga", "alfred" ] },
{ "name": "sandra", "friends": [ "elena" ] },
{ "name": "yves", "friends": [ "tiffany" ] }
]
Inline projection
要返回当前元素,请使用RETURN。 如果还存在FILTER,RETURN在其后面。
FOR u IN users
RETURN u.friends[* RETURN CONCAT(CURRENT.name, " is a friend of ", u.name)]
返回的结果为:
[
[
"tina is a friend of john",
"helga is a friend of john",
"alfred is a friend of john"
],
[
"sergei is a friend of yves",
"tiffany is a friend of yves"
],
[
"bob is a friend of sandra",
"elena is a friend of sandra"
]
]