ArangoDB自学笔记(万字!!全!!)
本文乃博主通过对Arangodb的官网自学后所做的笔记,可能有不足的地方,欢迎在评论区中指出,本人定虚心接受
本文是博主写在word上,再复制到博客中的,因此会有些排版问题,如果有影响阅读的地方,也可在评论区指出,或者私聊我
- 下载与安装
1.1下载
官网下载:www.arangodb.com
登录网页端:127.0.0.1:8529
1.2安装
- 解压下载的压缩包
- 用管理员模式运行命令提示符,找到解压文件的bin目录
- arangod --install-service ,出现如下的情况,即为安装成功
在服务中可以找到启动的ArangoDB
- 接着在bin目录下启动arangod.exe ,出现have fun,说明服务启动
- 再点击bin目录下的arangosh.exe,出现下图
直接回车
出现这样的结果,说明连接成功了
- 常用Shell命令
创建用户和密码 var users = require("@arangodb/users");
users.save("my_user", "my_password");
赋予权限 require("@arangodb/users").grantDatabase("my_user", "arangodb");
列出所有的数据库 db._databases();
创建新的数据库 db._createDatabase(“AAA”);
删除数据库 db._dropDatabase(“AAA”);
切换数据库 db._useDatabase(“AAA”);
创建集合 db._create(“test”);
删除集合 db._drop(“test”);
列出所有集合 db._collections();
更多命令通过 help查看
- CRUD
3.1创建/增加 C
创建一个users集合 db._create(“users”);
增加一条数据 INSERT { name : ”张三” , age: 27} INTO users
3.2查询 R
查询指定数据 RETURN DOCUMENT("users/9883")
查询多条数据 RETURN DOCUMENT(“users/9883”,”users/9665”)
DOCUMENT()返回值是数组
users :集合名
9883 :_key
查询所有的数据 FOR user IN users
FILTER user.age > 30
SORT user.age
LIMIT 2
RETURN user
表示对users集合进行迭代,以user作为变量名
FILTER :筛选的条件
如果字段值为null < 绝大多数字符,但不可靠
在实际生产的过程中,需要对null值进行处理
SORT :排序的关键字 默认ASC
可以进行多重排序,在后面添加字段
如:SORT user.name DESC,user.age DESC
LIMIT : 限制输出的个数
注意存在的位置,AQL的执行会按照语句顺序执行,提前LIMIT会对后续计算造成影响
RETURN: 输出结果
3.3更新/修改 U
修改一条数据 UPDATE "6432" WITH { sex : "man" } IN users
可用于为指定数据添加新的字段
替换一条数据 REPLACE"6432" WITH { sex : "man" } IN users
3.4删除D
删除一条数据 REMOVE "6432" IN users
- 其他简单操作
4.1 连接 CONCAT
连接字段 FOR user IN users
RETURN CONCAT("name is ",user.name,", sec is ",user.sex )
CONCAT中的字段以”,”连接
4.2多重循环
FOR user1 IN users
FOR user2 IN users
FILTER user1 != user2
RETURN [user1.name, user2.name]
自连接,将两个名字不同的组合输出
FOR user1 IN users
FOR user2 IN users
FILTER user1!=user2
RETURN {pair:[user1.name , user2.name],
sumAge:user1.age+user2.age}
自连接,名字组合成数组输出,并计算年龄总和
4.3临时变量LET
FOR user1 IN users
FOR user2 IN users
FILTER user1!=user2
LET sumAge=user1.age + user2.age
FILTER sumAge <100
RETURN {pair:[user1.name , user2.name],
sumAge:sumAge}
LET :定义一个临时变量 sumAge ,之后的临时变量可以直接使用
PS:此处sumAge:sumAge 可简写为 sumAge
4.4通过Document在A中查找B的数据(有join的味道)
FOR c IN Characters
RETURN DOCUMENT("Traits",c.traits)
以Traits集合为字典,输出Characters中traits特征的真实值
4.5 MERGE 替换/添加 特征 ****仅仅相当于一个文档的拼接
MERGE(A文档,B文档,C文档)
A文档中与B文档相同的特征会被替换,A文档中没有的特征会添加进去
替换A集合中的数据
下面两种方式实际上并没有替换集合中的数据,仅仅是在展示时将数据进行了拼接处理
方式一: 2.043ms
FOR c IN Characters
RETURN MERGE(c, { traits: DOCUMENT("Traits", c.traits)[*].en } )
方式二:
FOR c IN Characters
RETURN MERGE(c, {
traits: (
FOR key IN c.traits
FOR t IN Traits
FILTER t._key == key
RETURN t.en
)
})
- AQL语法
5.1语句类型
AQL的语句主要分为两种:
一种是查询语句,以RETURN返回
一种是操作语句,以(INSERT 、UPDATE、REPLACE、REMOVE)为主
5.2注释
AQL的注释分为两种:
单行注释 //
多行注释 /* ..... */
5.3关键字
关键字一般不能用作集合或者属性的名称,如果必须要用到的话,需要进行加”/”进行转义。且大部分关键字不区分大小写。
常用关键字
关键字 |
作用 |
FOR |
数组迭代 |
RETURN |
输出结果 |
FILTER |
条件过滤(非视图) |
SEARCH |
条件过滤(视图) |
SORT |
结果排序 |
LIMIT |
结果切片 |
LET |
变量定义 |
COLLECT |
结果分组 |
INSERT |
插入新文档 |
UPDATE |
(部分)更新现有文档 |
REPLACE |
替换指定文档 |
REMOVE |
删除指定文档 |
UPSERT |
插入新文档或更新现有文档 |
WITH |
指定查询中使用的集合 |
可以作为集合名或属性名的关键字
关键字 |
作用 |
KEEP |
COLLECT的变体 |
COUNT(WITH COUNT INTO) |
COLLECT的变体 |
OPTIONS |
在UPDATE / REPLACE / UPSERT / REMOVE操作之后使用,代表修改前的数据 |
PRUNE |
图形遍历,FOR的变体 |
SEARCH |
搜索操作 |
TO |
最短路径图的遍历中使用 |
关键字 |
作用 |
CURRENT |
在数组内联表达式中使用 |
NEW |
在INSERT / UPDATE / REPLACE / UPPERT 操作之后使用,代表修改后的数据 |
OLD |
在UPDATE / REPLACE / UPSERT / REMOVE操作之后使用,代表修改前的数据 |
区分大小写的关键字
5.4名字(集合名、属性名、函数名、变量名)
关键字不能当作名字使用,如果使用关键字的话,需要转义,如:
FOR doc IN `filter`
RETURN doc.`sort`
PS:这个转义字符是波浪线那个键,不是单引号 ’ 或者 ”
变量名:
允许使用的字符为字母a到z(大小写),数字0到9,下划线(_)符号和美元($)符号。
但是不能以数字开头。
如果变量名以下划线字符开头,则必须在下划线后跟至少一个字母或数字。
- AQL数据类型
数据类型 |
描述 |
null |
空值 |
boolean |
布尔值,可能值为false和true |
number |
整数、小数 |
String |
UTF-8的文本值 |
Array |
序列化的数组数据,可以通过索引使用 |
Object |
序列化的对象数据,可以通过属性名去使用 |
- 绑定参数
FOR u IN users
FILTER u.name ==@name
RETURN u
@后可以跟字母和数字,作为绑定参数
在web页面中可以在右侧的界面中输入参数
在命令行中执行时,可以输入
{
"query": "FOR u IN users FILTER u.id == @id RETURN u",
"bindVars": {
"name": "张三"
}
}
如果在AQL中需要用到字符串连接处理,如:(需要使用字符串函数进行连接)
FOR u IN users
FILTER u.id == CONCAT('prefix', @id, 'suffix') && u.name == @name
RETURN u
绑定参数也可以用于获取对象属性,或者作为数组的索引,如:
LET doc = { foo: { bar: "baz" } }
RETURN doc.@attr.@subattr
// or
RETURN doc[@attr][@subattr]
对于高度嵌套的数据,如:
LET doc = { a: { b: { c: 1 } } }
RETURN doc.@attr
此时,要想获取到数值1,需要输入的绑定参数,不是 “a.b.c”,而是[ "a", "b", "c" ]
如果将绑定参数用于集合名,如:
FOR u IN @@collection
FILTER u.active == true
RETURN u
此时就需要使用 @@来表示绑定参数
PS:关键字不能用绑定参数来代替
- 数据类型与值的顺序
AQL比较数据的时候采用的是确定性算法,先比较数据类型,再比较值的大小
数据类型之间的大小关系如下:
null < boolean < number < string < array/list < object/document
这说明,null是AQL中最小的类型,而object是最大的类型,如果比较的双方数据类型不同,则按上述规则排序,
具体比较规则可根据下方来比较:
null < false < true < 0 < ‘’ < ’ ’ < ’0’ < ‘abc’ < [ ](数组) < { } (对象)
如果是两个复合型的数据比较,如:两个数组比较 [1,2] 与 [2,3]
递归比较其中的子元素
如:
[ ] < [0] 相当于 null < 0
- < [1]
[1,2]<[2]
如果是两个对象进行比较,如果对象内部的属性值对应相等,则整体相等,其他则按上述规则进行比较
如:
{ “a” : 1 , ”b” : 2 } == {“b”:2 , “a”:1}
- 错误
产生运行时异常的原因主要有:
- 除零异常:除数为0
- 算术运算符中的无效操作数:非数字值用于算术运算符时发生
- 逻辑运算符中的无效操作数:在逻辑运算中使用任何非布尔值作为操作数时发生
- AQL的局限性
- 一个AQL查询不能使用超过1000条结果寄存器(这是个什么东西?)
- 一个AQL查询不能使用超过2048个集合
- 在同一个AQL语句中,对A集合进行了写入操作,就不能对A集合进行读取操作
- 必须在查询的初始的with语句中声明动态访问的所有集合。
- 表达式内部的子查询会先一步执行,这意味着子查询不会参与操作数的惰性求值(惰性求值是什么?)
- 运算符
比较运算符:可以与任何数据类型一起使用,返回值为布尔类型
操作符 |
描述 |
== |
等于 |
!= |
不等于 |
< |
小于 |
<= |
小于等于 |
> |
大于 |
>= |
大于或等于 |
IN |
是否包含在数组中 |
NOT IN |
是否不包含在数组中 |
LIKE |
字符串是否与模式匹配 |
NOT LIKE |
字符串值是否与模式不匹配 |
=~ |
字符串值是否与正则表达式匹配 |
!~ |
字符串值是否与正则表达式不匹配 |
数组比较运算符:用于数组之间进行比较,在比较运算符前多了使用前缀ALL,ANY或NONE,数组比较运算符左侧都为数组,如:
[ 1, 2, 3 ] ALL IN [ 2, 3, 4 ] // false
[ 1, 2, 3 ] ALL IN [ 1, 2, 3 ] // true
[ 1, 2, 3 ] NONE IN [ 3 ] // false
[ 1, 2, 3 ] NONE IN [ 23, 42 ] // true
[ 1, 2, 3 ] ANY IN [ 4, 5, 6 ] // false
[ 1, 2, 3 ] ANY IN [ 1, 42 ] // true
[ 1, 2, 3 ] ANY == 2 // true
[ 1, 2, 3 ] ANY == 4 // false
[ 1, 2, 3 ] ANY > 0 // true
[ 1, 2, 3 ] ANY <= 1 // true
[ 1, 2, 3 ] NONE < 99 // false
[ 1, 2, 3 ] NONE > 10 // true
[ 1, 2, 3 ] ALL > 2 // false
[ 1, 2, 3 ] ALL > 0 // true
[ 1, 2, 3 ] ALL >= 3 // false
["foo", "bar"] ALL != "moo" // true
["foo", "bar"] NONE == "bar" // false
["foo", "bar"] ANY == "foo" // true
逻辑运算符:AQL中的两个操作数逻辑运算符将使用短路评估来执行,如果有子查询,则先执行子查询并提前进行评估
与运算符:&& 或者 AND
或运算符:|| 或者 OR
非运算符: ! 或者 NOT
PS:非布尔值数据转换规则:
null 转换为 false
非零数字为 true
数字零为 false
空字符串为 false
其他字符串为 true
数组和对象都为 true
PPS:逻辑与 和 逻辑或 的返回值可以是任何数据类型,如:
1 || 7 // 1
null || "foo" // "foo"
null && true // null
true && 23 // 23
算术运算符:对两个操作数执行算术运算,返回值是一个数字
+ 加
- 减
* 乘
/ 除
% 取余
同时,AQL支持正负号,即一元加号 +2 与一元减号 -2
AQL求幂采用函数POW(),不支持 ** 、exp等操作
求字符串连接必须使用字符串函数 CONCAT() , “a”+”b” 这样是不起作用的
PS:算术运算符接受任何类型的操作数。将非数字类型的操作数传递给算术运算符将根据TO_NUMBER()函数的转换规则将其他类型转换为数字类型
null 0
false 0
true 1
NaN 0
Infinity 0
字符串开头和结尾的空格都将被忽略,非数字的字符转换为0,数字还是转换为对应数字
空数组 0
具有一个元素的数组,转换成该元素的数字表示形式
具有多个元素的数组,转换为0
对象转换为0
PPS:发生除0异常时会产生结果null,会发出警告,但是查询不会终止
三目运算符:如果第一个操作数为true,则返回第二个操作数的结果,否则返回第三个操作数的结果
如:u.age > 15 || u.active == true ? u.userId : null
如果u.age > 15 || u.active == true 为true则返回userId,否则,返回null
变体:如果为true的返回值与表达式的值相同,则可简写
u.value ? : 'value is null, 0 or not present'
该表达式表示,如果u.value为true,则返回u.value,否则返回字符串
范围运算符:AQL支持使用 .. 表达简单的数字范围,是闭区间
如:2010..2013
输出:[2010,2011,2012,2013]
数组运算符:[*]表示数组所有元素
远算符优先级: 优先级从低到高
运算符 |
描述 |
, |
逗号分隔符 |
DISTINCT |
返回去重 |
? : |
三目运算符 |
= |
变量赋值(LET操作) |
WITH |
与运算符(WITH / UPDATE / REPLACE / COLLECT操作) |
INTO |
进入运算符(INSERT / UPDATE / REPLACE / REMOVE / COLLECT操作) |
|| |
逻辑或 |
&& |
逻辑与 |
OUTBOUND,INBOUND,ANY,ALL,NONE |
数组比较运算符 |
==,!=,LIKE,NOT LIKE,=~,!~ |
(in)相等,通配符(非)匹配,正则表达式(非)匹配 |
IN, NOT IN |
(不是)在运算符中 |
<,<=,>=,> |
小于,小于等于,大于等于,大于 |
.. |
范围运算符 |
+, - |
加,减 |
*,/,% |
乘法,除法,取余 |
!,+,- |
逻辑否定,一元加,一元减 |
() |
函数调用 |
. |
会员访问 |
[] |
索引值访问 |
[*] |
扩张 |
- 高级操作
FOR: 迭代
通用的语法:
FOR u IN users
RETURN u
使用静态数组进行遍历:
FOR year IN [ 2011, 2012, 2013 ]
RETURN { "year" : year, "isLeapYear" : year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) }
多循环嵌套:返回两个表的笛卡尔积
FOR u IN users
FOR l IN Locations
RETURN {"user":u , "locations":l}
RETURN:输出结果
通用的语法:
RETURN 表达式
返回集合中的所有元素:
FOR u IN users
RETURN u
返回多个属性: 可以构造一个对象
FOR u IN users
RETURN { name: u.name, age: u.age }
PS:RETURN会关闭当前作用域,并消除其中所有的临时变量
动态的属性名: [] 不能去除
FOR u IN users
RETURN {[u._id] : u.age}
MERGE将结果合并输出:
RETURN MERGE(
FOR u IN users
RETURN {[u._id] : u.age})
返回值唯一:
从2.7版本开始,可以在RETURN后加上DISTINCT来确保数据唯一性
FOR u IN users
RETURN DISTINCT u.name
DISTINCT 不会作用于子查询的查询结果,如:
FOR what IN 1..2
RETURN DISTINCT (
FOR i IN [ 1, 2, 3, 4, 1, 3 ]
RETURN i
)
返回值为:
[
[
1,
2,
3,
4,
1,
3
]
]
FILTER: 过滤条件
通用语法:
FILTER 表达式
表达式的结果必须是false或true
多个FILTER:多个FILTER的使用类似于AND的判断,必须满足所有的FILTER,结果才能输出
FOR u IN users
FILTER u.active == true
FILTER u.age < 39
RETURN u
FILTER顺序:操作语句的顺序会大大影响AQL语句的执行结果
FOR u IN users FOR u IN users
FILTER u.active == true LIMIT 5
LIMIT 5 FILTER u.active == true
RETURN u RETURN u
这两条语句的执行结果就有可能大大的不同
左边的语句是在存活的user中选5位输出
右边的则是在5位user中选存活的输出
结果相差很大
SEARCH:视图内的查找
在视图中使用
SEARCH与FILTER类似,但有不同
必须紧接在FOR..IN..之后
在3.6.0版本之后,SEARCH支持数组比较符,如:
LET tokens = TOKENS("some input", "text_en") // ["some", "input"]
FOR doc IN myView SEARCH tokens ALL IN doc.title RETURN doc
FOR doc IN myView SEARCH tokens ANY IN doc.title RETURN doc
SORT: 排序
通用语法: 默认 升序
SORT 表达式 排序方式
可指定多重排序
SORT doc.lastName ASC, doc.firstName DESC
先按姓氏升序排序,再按名字降序排序
LIMIT: 限制输出个数
通用语法:
LIMIT COUNT
LIMIT offset,count
如:
LIMIT 5 == LIMIT 0,5
LET: 定义临时变量
通用语法:
LET 变量名= 表达式
变量在AQL中是不可变的,且不能被再次分配,如:
LET a = [1, 2, 3] //定义变量
a = PUSH(a, 4) // 修改a的值,错误 ×
LET a = PUSH(a, 4) // 为a重新赋值 错误 ×
LET b = PUSH(a, 4) // 重新定义b来赋值 √ 结果: [1, 2, 3, 4]
COLLECT: collect 的千种用法 类似于group by
第一种用法,类似LET,变相的去重:
FOR u IN users
COLLECT name = u.name
RETURN name
第二种用法,类似于sql中的group
FOR u IN users
COLLECT name = u.name INTO groups
RETURN {
name:name,
users:groups
}
将相同名字的文档放到同一个groups中,然后输出,类似于group by name
第三种用法,多重分组
FOR u IN users
COLLECT country = u.country, city = u.city INTO groups
RETURN {
"country" : country,
"city" : city,
"usersInCity" : groups
}
先按照country分组,再按city分组,多重分组
第四种用法,分组显示时保留需要的字段
FOR u IN users
COLLECT name = u.name INTO groups = u.age
RETURN {
name:name,
age : groups
}
在展示groups时,只会显示相同名字的人的年龄
第五种用法,KEEP保留字段
FOR u IN users
LET name = u.name
LET someCalculation = u.value1 + u.value2
COLLECT city = u.city INTO groups KEEP name
RETURN {
"city" : city,
"userNames" : groups[*].name
}
此处name因为被KEEP,所以在groups中得到保留,而someCalculation则没有被保留
第六种用法,WITH COUNT
FOR u IN users == RETURN LENGTH(users)
COLLECT WITH COUNT INTO length
RETURN length
上面两条语句等效,但是左边的效率要略低于右边的语句
第七种,按照跨度进行分组
第一种写法
FOR u IN users
COLLECT ageGroup = FLOOR(u.age / 20) * 20 INTO g
RETURN {
"ageGroup" : ageGroup,
"minAge" : MIN(g[*].u.age),
"maxAge" : MAX(g[*].u.age)
}
第二种写法
FOR u IN users
COLLECT ageGroup = FLOOR(u.age / 20) * 20
AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
RETURN {
ageGroup,
minAge,
maxAge
}
两种写法的结果是一样的,但是第二种写法的效率要高于第一种写法
REMOVE: 删除数据 删除操作要么全部成功,要么全部失败
通用语法:
REMOVE keyExpression IN collection options
必须包含要删除的_key
以下三种等效
FOR u IN users
REMOVE { _key: u._key } IN users
FOR u IN users
REMOVE u._key IN users
FOR u IN users
REMOVE u IN users
每个查询和集合只能执行一次删除语句
REMOVE 'john' IN users
REMOVE 'john' IN backups // 可以,因为是不同的集合
REMOVE 'mary' IN users // 不行,因为又对users集合删除
设置选项:OPTION
案例:
FOR i IN 1..1000
REMOVE { _key: CONCAT('test', i) } IN users
案例语句如果要删除的文档不存在,则所有删除语句全部失效
ignoreErrors:忽略错误
FOR i IN 1..1000
REMOVE { _key: CONCAT('test', i) } IN users OPTIONS { waitForSync: true }
如果要删除的文档不存在,依然可以将其他存在的文档删除
ignoreRevs:忽略已经更新过的数据
FOR i IN 1..1000
REMOVE { _key: CONCAT('test', i), _rev: "1287623" } IN users OPTIONS { ignoreRevs: false }
UPDATE:更新数据
内部属性(例如_id,_key,_rev, _from和_to)无法更新
通用语法: 必须包含可以识别的_key
UPDATE document IN collection options
UPDATE keyExpression WITH document IN collection options
以下语句等价:
FOR u IN users
UPDATE u._key WITH { name: CONCAT(u.firstName, " ", u.lastName) } IN users
FOR u IN users
UPDATE { _key: u._key } WITH { name: CONCAT(u.firstName, " ", u.lastName) } IN users
FOR u IN users
UPDATE u WITH { name: CONCAT(u.firstName, " ", u.lastName) } IN users
需要有可以被识别的_key
基于当前值进行修改
UPDATE doc WITH {
karma: doc.karma + 1
} IN users
选项设置
ignoreErrors:忽略错误
FOR i IN 1..1000
UPDATE {
_key: CONCAT('test', i)
} WITH {
foobar: true
} IN users OPTIONS { ignoreErrors: true }
keepNull:允许空值存在
使用空值更新属性时,ArangoDB不会从文档中删除该属性,但会为其存储一个空值。如果想要删除该属性,则设置keepNull为false,如:
FOR u IN users
UPDATE u WITH {
foobar: true,
notNeeded: null
} IN users OPTIONS { keepNull: false }
mergeObjects:是否合并对象内容
初始数据
FOR u IN users
LIMIT 1
UPDATE u WITH {
name: { first: "foo", middl: "b.", last: "baz" }
} IN users OPTIONS { mergeObjects: true }
RETURN NEW
执行过后,name中对象的内容变多了
FOR u IN users
LIMIT 1
UPDATE u WITH {
name: { first: "foo", middle: "b.", last: "baz" }
} IN users OPTIONS { mergeObjects: false }
RETURN NEW
执行过后,name中对象的内容就是更新的内容,相当于是覆盖了
所以说,mergeObjects的作用就是:true时,如果更新的对象内部存在没有被更新的属性,会保留这些属性;false时,会直接覆盖掉原来对象的内容。
MergeObjects默认为true
REPLACE:
全部操作要么都成功,要么都失败
一个AQL语句只能对同一个集合操作一次
且条件语句中必须有_key属性
替换将完全替换现有文档,但不会修改内部属性(例如_id,_key,_from和_to)的值
替换文档将使用服务器生成的值来修改文档的修订号
通用语法:
REPLACE document IN collection options
REPLACE keyExpression WITH document IN collection options
以下查询是等效的:
FOR u IN users
REPLACE { _key: u._key, name: CONCAT(u.firstName, u.lastName) } IN users
FOR u IN users
REPLACE u._key WITH { name: CONCAT(u.firstName, u.lastName) } IN users
FOR u IN users
REPLACE { _key: u._key } WITH { name: CONCAT(u.firstName, u.lastName) } IN users
FOR u IN users
REPLACE u WITH { name: CONCAT(u.firstName, u.lastName) } IN users
选项设置:
ignoreErrors:忽略错误
FOR i IN 1..1000
REPLACE { _key: CONCAT('test', i) } WITH { foobar: true } IN users OPTIONS { ignoreErrors: true }
ignoreRevs:是否忽略修订号
FOR i IN 1..1000
REPLACE { _key: CONCAT('test', i), _rev: "1287623" } WITH { foobar: true } IN users OPTIONS { ignoreRevs: false }
INSERT:
插入边集合时,必须指定_from和_to属性
插入普通集合时,可无需指定_key
通用语法:
INSERT document INTO collection [ OPTIONS options ]
选项设置:
ignoreErrors:忽略因为_key冲突引起的问题
FOR i IN 1..1000
INSERT {
_key: CONCAT('test', i),
name: "test",
foobar: true
} INTO users OPTIONS { ignoreErrors: true }
waitForSync :确保插入查询返回时数据是持久的
FOR i IN 1..1000
INSERT {
_key: CONCAT('test', i),
name: "test",
foobar: true
} INTO users OPTIONS { waitForSync: true }
overwrite:如果_key冲突,是否要覆盖数据
FOR i IN 1..1000
INSERT {
_key: CONCAT('test', i),
name: "test",
foobar: true
} INTO users OPTIONS { overwrite: true }
overwriteMode:多种选择,多样人生
ignore:如果_key值冲突,则忽略
replace:如果_key值冲突,则替换原数据
update:如果_key值冲突,部分更新
confict:如果_key值冲突,则报错
FOR i IN 1..1000
INSERT {
_key: CONCAT('test', i),
name: "test",
foobar: true
} INTO users OPTIONS { overwriteMode: "update", keepNull: true, mergeObjects: false }
UPSERT: 检查部分文档是否存在
操作仅限于一个集合
常与INSERT于UPDATE联用
通用语法:
UPSERT searchExpression INSERT insertExpression UPDATE updateExpression IN collection options
UPSERT searchExpression INSERT insertExpression REPLACE updateExpression IN collection options
案例:
如果文档存在,其登录属性将增加一。如果不存在,将插入一个新文档,其中包括属性name,logins和dateCreated
UPSERT { name: 'superuser' }
INSERT { name: 'superuser', logins: 1, dateCreated: DATE_NOW() }
UPDATE { logins: OLD.logins + 1 } IN users
选项设置:与INSERT 和 UPDATE类似,不再举例
局限性:
UPSERT是非原子性的,如果多个UPSERT并发执行,则可能会多次添加文档
应该对UPSERT搜索的属性创建唯一性索引,可以提高UPSERT的性能
WITH:
AQL可以用WITH语句开头
WITH中指定的集合,都将被锁定
WITH可以避免死锁,从3.1版本开始使用
- 高级函数
13.1 ArrangoSearch函数 紧跟SEARCH
通用语法:
ANALYZER(<expression>, …)
STARTS_WITH(doc.attribute, …)
ANALYZER 没看懂
通用语法
ANALYZER(expr, analyzer)
注:
expr(表达式):任何有效的搜索表达式
analyzer(string):分析器的名称。
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
BOOST
通用语法
BOOST(expr, boost)
注:
expr(表达式):任何有效的搜索表达式
boost(数字):数字提升值
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
案例:
数据源:
{ "text": "foo bar" }
{ "text": "foo" }
{ "text": "bar" }
{ "text": "foo baz" }
{ "text": "baz" }
AQL语句:
FOR doc IN viewName
SEARCH ANALYZER(BOOST(doc.text == "foo", 2.5) OR doc.text == "bar", "text_en")
LET score = BM25(doc)
SORT score DESC
RETURN { text: doc.text, score }
结果:
[
{
"text": "foo bar",
"score": 2.787301540374756
},
{
"text": "foo baz",
"score": 1.6895781755447388
},
{
"text": "foo",
"score": 1.525835633277893
},
{
"text": "bar",
"score": 0.9913395643234253
}
]
EXISTS
通用语法:
EXISTS(path)
EXISTS(path, type)
EXISTS(path, "analyzer", analyzer)
注:
path(属性路径表达式):文档中要测试的属性
type(字符串)要测试的数据类型,可以是以下之一:
"null"
"bool" / "boolean"
"numeric"
"string"
"analyzer"
Analyzer(字符串,可选):Analyzer的名称。ANALYZER()如果未指定,默认为"identity"
案例一:
FOR doc IN viewName
SEARCH EXISTS(doc.text)
RETURN doc
案例二:
FOR doc IN viewName
SEARCH EXISTS(doc.text, "string")
RETURN doc
案例三:
FOR doc IN viewName
SEARCH EXISTS(doc.text, "analyzer", "text_en")
RETURN doc
IN_RANGE
通用语法:
IN_RANGE(path, low, high, includeLow, includeHigh)
注:
path(属性路径表达式):文档中要测试的属性的路径
low(数字|字符串):所需范围的最小值
high(数字|字符串):所需范围的最大值
includeLow(布尔):最小值是否包含在范围内
includeHigh(布尔):最大值是否包含在范围内
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
案例:
FOR doc IN viewName
SEARCH IN_RANGE(doc.value, 3, 5, true, true)
RETURN doc.value
查找doc.value大于等于3,且小于等于5的文档
MIN_MATCH
通用语法:
MIN_MATCH(expr1, ... exprN, minMatchCount)
注:
expr(表达式,可重复):任何有效的搜索表达式
minMatchCount(数字):应满足的最小搜索表达式数
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
案例:
FOR doc IN viewName
SEARCH ANALYZER(MIN_MATCH(doc.text == 'quick', doc.text == 'brown', doc.text == 'fox', 2), "text_en")
RETURN doc.text
寻找至少能满足其中两条表达式的文档
NGRAM_MATCH 在3.7版本引入
通用语法:
NGRAM_MATCH(path, target, threshold, analyzer)
注:
path(属性路径表达式|字符串):文档或字符串中属性的路径
target(字符串):要与存储的属性进行比较的字符串
threshold(数字,可选):0.0和之间的值1.0。0.7如果未指定,则默认为。
analyzer(string):分析器的名称。
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
匹配采用的是N-GRAM算法
N-GRAM算法:s=Gorbachev,target=Gorbechyov
将字符串按每N个字符进行分割,
s Go or rb ba ac ch he ev 共8个字符串
target Go or rb be ec ch hy yo ov 共9个字符串
根据公式|GN(s)|+|GN(t)|−2×|GN(s)∩GN(t)|进行计算
GN(s)是s在N的条件下分割的字符串数
GN(t)是target在N的条件下分割的字符串数
GN(s)∩GN(t)是GN(s)与GN(t)相同的字符串数
所以计算结果为:8+9-2*4=9
所以N-GRAM相似度为9,很明显,这里的相似度越小说明s与target越接近
但是Arangodb的阈值应大于0,小于1,说明NGRAM的值需要再除以某一个参数
案例:
FOR doc IN viewName
SEARCH NGRAM_MATCH(doc.text, "quick blue fox", 0.9, "bigram")
RETURN doc.text
PHRASE 不太懂
通用语法:
PHRASE(path, phrasePart, analyzer)
PHRASE(path, phrasePart1, skipTokens1, ... phrasePartN, skipTokensN, analyzer)
注:
path(属性路径表达式):文档中要测试的属性
statementPart(字符串|数组|对象):在标记中搜索的文本。也可以是由字符串,数组和对象标记 在3.7版本引入对象,在3.6版本引入数组
skipTokens(数字,可选):视为通配符的令牌数量
Analyzer(字符串,可选):Analyzer的名称。ANALYZER()如果未指定,则使用包装调用的分析器,或者默认为"identity"
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
案例:
FOR doc IN viewName
SEARCH PHRASE(doc.text, "lorem ipsum", "text_en")
RETURN doc.text
STARTS_WITH
通用语法
STARTS_WITH(path, prefix)
STARTS_WITH(path, prefixes, minMatchCount) 3.7版本后引入
注:
path(属性路径表达式):文档中要比较的属性的路径
prefixes(数组):要在文本开头搜索的字符串数组
minMatchCount(数字,可选):应满足的搜索前缀的最小数量。默认1
不返回任何内容:该函数只能在SEARCH操作中调用, 否则将引发错误
案例:
FOR doc IN viewName
SEARCH ANALYZER(STARTS_WITH(doc.text, ["wrong", "ips"], 1), "text_en")
RETURN doc.text
搜索满足wrong,ips 至少一个为前缀的doc.text 文档
LEVENSHTEIN_MATCH 3.7版本引入
通用语法:
LEVENSHTEIN_MATCH(path, target, distance, transpositions, maxTerms)
注:
path(属性路径表达式):文档中要比较的属性的路径
target(字符串):要与存储的属性进行比较的字符串
distance(数字)的最大编辑距离,它可以是间 0和4如果换位是false,和之间0和3如果它是true
transpositions(bool,可选):如果设置为false,则计算Levenshtein距离,否则计算Damerau-Levenshtein距离(默认)
Levenshtein距离是直接删除、添加数据
Damerau-Levenshtein距离是先移动数据,再考虑删除、添加
maxTerms(数字,可选):仅考虑指定数量的最相关术语。可以0考虑所有匹配的术语,但这可能会对性能产生负面影响。默认值为64。
LIKE
通用语法:
LIKE(path, search)
注:
path(属性路径表达式):文档中要比较的属性的路径
search(字符串):一种搜索模式,可以包含通配符 %(意味着任何字符序列,包括无)和_(任何单个字符)。文字%和_必须以两个反斜杠(四arangosh)进行转义。
类似于sql中的like
案例:
FOR doc IN viewName
SEARCH ANALYZER(LIKE(doc.text, "foo%b_r"), "text_en")
RETURN doc.text
13.2数组函数
append 将一个数组的元素添加到另一个数组的右侧
通用语法:
APPEND(anyArray, values, unique)
注:
anyArray(数组):具有任意类型元素的数组
value(array | any):数组,其元素应添加到anyArray
unique(布尔值,可选):如果设置为true,则仅添加anyArray中尚未包含的那些值。默认值为false。
返回newArray(数组):修改后的数组
COUNT_DISTINCT 数组中非重复数据计数
通用语法:
COUNT_DISTINCT(anyArray)
注:
anyArray(数组):具有任意类型元素的数组
FIRST 获取数组中第一个元素
通用语法:
FIRST(anyArray)
案例:
RETURN FIRST([ 1,2,3 ])
结果:
[
1
]
FLATTEN 打平表 将数组内的数组展开
通用语法:
FLATTEN(anyArray, depth)
注:
anyArray(数组):具有任意类型元素的数组,包括嵌套数组
depth(数字,可选):展平深度,默认值为1
返回flatArray(数组):展平的数组
案例:
RETURN FLATTEN([ 1,2,[ 3,4 ],5,[ 6,7 ],[ 8,[ 9,10 ]]])
只展平1层
结果:
[
[ 1,
2,
3,
4,
5,
6,
7,
8,
[ 9,
10
]
]
]
[9,10]的数组并未展平,因为只展平一层
INTERLEAVE 将数组交错融合成新的数组 3.7版本引入
通用语法:
INTERLEAVE(array1, array2, ... arrayN)
注:
array(array,repeatable):任意数量的数组作为多个参数(至少2个)
返回newArray(数组):交错的数组
案例一:
RETURN INTERLEAVE( [1, 1, 1], [2, 2, 2], [3, 3, 3] )
结果:
[
[ 1,
2,
3,
1,
2,
3,
1,
2,
3
]
]
如果有数组的个数不足,则跳过
案例二:
RETURN INTERLEAVE([ 1 ],[ 2,2 ],[ 3,3,3 ])
结果:
[
[ 1,
2,
3,
2,
3,
3
]
]
INTERSECTION 返回所有数组的交集
通用语法:
INTERSECTION(array1, array2, ... arrayN)
案例:
RETURN相交点([ 2,4,6 ],[ 8,10,12 ],[ 14,16,18 ])
结果:
[
[]
]
JACCARD 求交集元素个数在并集元素个数的比例 3.7引入
通用语法:
JACCARD(array1, array2)
案例:
RETURN JACCARD([ 1,2,3,4 ],[ 3,4,5,6 ])
结果:
[
0.3333333333333333
]
交集是[3,4]
并集是[1,2,3,4,5,6]
所以结果是0.333333
案例二:
RETURN JACCARD([ 1,1,2,2,2,3 ],[ 2,2,3,4 ])
结果:
[
0.5
]
交集是[2,3]
并集是[1,2,3,4]
所以结果是0.5
案例三:
RETURN JACCARD([ 1,2,3 ],[])
结果:
0
交集是[]
并集是[1,2,3]
结果是0
案例四:
RETURN JACCARD([],[])
结果:
1
交集是[]
并集是[]
所以结果是1
LAST 返回数组最后一个元素
通用语法:
LAST(AnyArray)
案例:
RETURN LAST([ 1,2,3,4,5 ])
结果:
[
5
]
LENGTH 返回各类数据的长度
通用语法:
LENGTH(AnyArray)
注:
AnyArray可以是数组、数字、字符串、布尔值、null、对象
输入值 |
长度 |
String |
字符长度 |
Number |
数字长度 |
Array |
元素数 |
Object |
一级元素数量 |
True |
1 |
False |
0 |
null |
0 |
案例:
RETURN LENGTH( {a:1, b:2, c:3, d:4, e:{f:5,g:6}} )
结果:
[
5
]
因为一级元素只有a、b、c、d、e
MINUS 返回仅在第一个数组中出现的元素
通用语法:
MINUS(array1, array2, ... arrayN)
案例:
RETURN MINUS([1,2,3,6,7],[2,3,4],[4,5,6])
结果:
[
[
1,
7
]
]
OUTERSECTION 返回所有数组中仅出现一次的元素
通用语法:
OUTERSECTION(array1, array2, ... arrayN)
案例:
RETURN OUTERSECTION([ 1,2,3 ],[ 2,3,4 ],[ 3,4,5 ])
结果:
[
[ 5,
1
]
]
POSITION
通用语法:
POSITION(anyArray, search, returnIndex)
注:
anyArray(数组):一个包含任意类型元素的数组
search(任意):任意类型的元素,要查找的元素
returnIndex(bool,可选):如果设置为true,则返回匹配的位置而不是布尔值。默认值为false。
案例:
RETURN POSITION( [2,4,6,8], 4, true )
结果:
[
1
]
PUSH
通用语法:
PUSH(anyArray, value, unique)
注:
anyArray(数组):具有任意类型元素的数组
value(任何):任意类型的元素
unique(bool):如果设置为true,则如果数组中已经存在值,则不添加值。默认值为false。
案例:
RETURN PUSH([ 1,2,2,3 ],2,true)
结果:
[
[ 1,
2,
2,
3
]
]
REMOVE_NTH 删除指定位置元素
通用语法:
REMOVE_NTH(anyArray, position)
注:
anyArray(数组):具有任意类型元素的数组
position(数字):要删除的元素的位置。位置从0开始。支持负位置,-1是最后一个数组元素。如果position超出范围,则返回的数组将保持不变。
返回值:删除元素后的数组
REPLACE_NTH 替换指定位置元素 3.7版本引入
通用元素:
REPLACE_NTH(anyArray, position, replaceValue, defaultPaddingValue)
注:
anyArray(数组):具有任意类型元素的数组
position(数字):要替换的元素的位置。位置从0开始。支持负位置,-1是最后一个数组元素。如果负位置超出范围,则将其设置为第一个元素(0)
replaceValue要在位置插入的值
如果position等于数组长度,则添加replaceValue
如果它大于数组长度,defaultPaddingValue附加到anyarray的根据需要的地方多次replaceValue在位置
如果在上述情况下未提供defaultPaddingValue,则引发查询错误
也就是说,如果position的值大于数组长度,会用defaultPaddingValue进行补位,直到可以将replaceValue插入
案例:
REPLACE_NTH([ “ a”,“ b”,“ c” ],6,“ z”,“ y”)
结果:
[
[ “ a”,
“ b”,
“ c”,
“ y”,
“ y”,
“ y”,
“ z”
]
]
REMOVE_VALUE 删除数组中的指定元素,可限制删除个数
通用语法:
REMOVE_VALUE(anyArray, value, limit)
注:
anyArray(数组):具有任意类型元素的数组
value(任何):任意类型的元素
limit(数量,可选):限制删除的个数
案例:
RETURN REMOVE_VALUE([ “ a”,“ b”,“ b”,“ a”,“ c” ],“ a”,1)
REVERSE 反转数组
通用语法:
REVERSE(anyArray)
案例:
RETURN REVERSE([ 2,4,6,8,10 ])
结果:
[
[ 10,
8,
6,
4,
2
]
]
SLICE 数组切片
通用语法:
SLICE(anyArray, start, length)
注:
anyArray(数组):具有任意类型元素的数组
start(数字):在此元素处开始提取。位置从0开始。负值表示从数组末尾开始的位置。
length(数字,可选):提取最大长度的元素,如果负(不包括),则提取从开始到长度的所有元素
案例:
RETURN SLICE([ 1,2,3,4,5 ],1,-1)
结果:
[
[ 2,
3,
4
]
]
SORTED 数组排序
通用语法:
SORTED(anyArray)
案例:
RETURN SORTED([ 8,4,2,10,6 ])
结果:
[
[ 2,
4,
6,
8,
10
]
]
UNION 数组合并
通用语法:
UNION(array1, array2, ... arrayN)
案例:
RETURN UNION(
[ 1,2,3 ],
[ 1,2 ]
)
结果:
[
[ 1,
2,
3,
1,
2
]
]
13.3日期函数
注:DATE表示时间戳和日期格式均可
DATE_NOW(timestamp) 获取当前时间的时间戳
DATE_TIMESTAMP(date) 将时间日期转换为时间戳
DATE_ISO8601(timestamp) 将时间戳转换为日期时间 (不是北京时间)
DATE_DAYOFWEEK(DATE) 返回星期几
DATE_YEAR(DATE) 年
DATE_MONTH(DATE) 月
DATE_DAY(DATE) 日
DATE_HOUR(DATE) 时
DATE_MINUTE(DATE) 分
DATE_SECOND(DATE) 秒
DATE_LEAPYEAR(DATE) 判断是否是闰年
DATE_DAYS_IN_MONTH(DATE) 返回日期所在月份的天数
DATE_ROUND(date, amount, unit) 根据指定时间单位按数量分桶
注:
date(字符串|数字):日期字符串或时间戳
amount(数量):必须为正整数值。
unit(字符串):以下任一项来指定时间单位
d, day, days 日
h, hour, hours 时
i, minute, minutes 分
s, second, seconds 秒
f, millisecond, milliseconds 毫秒
DATE_FORMAT(date, format) 将时间戳转换为指定的日期格式
常用格式:
RETURN DATE_FORMAT(DATE_NOW(), "%yyyy.%mm.%dd %hh:%ii:%ss,%fff")
DATE_ADD(date, amount, unit) 在日期上增加或减少时间
注:
date(数字|字符串):数字时间戳或ISO 8601日期时间字符串
amount(字符串):要加(正值)或减去(负值)的单位s的数量。建议仅使用正值,而应使用DATE_SUBTRACT()进行减法。
unit(字符串):以下任意一项
y,year,年
m,month,月
w,week,周
d,day,天
h,hour,小时
i,minute,分钟
s,second,秒
f,millisecond,毫秒
DATE_DIFF(date1, date2, unit, asFloat) 求时间差
注:
unit:返回值的单位,年、月、日、周......
asFloat(布尔值):是否保留小数
局限性:
不允许出现1583年之前的数据,因为他们在公历日期被正式引入之前
13.3文档函数
ATTRIBUTES 将文档的属性名输出
通用语法:
ATTRIBUTES(document, removeInternal, sort)
注:
document(对象):任意文档/对象
removeInternal(布尔型,可选):是否要在结果中省略所有系统属性(_key,_id等,每个以下划线开头的属性键)。默认值为false。
sort(布尔型,可选):可选地按字母顺序对结果数组进行排序。默认值为false,将以任何顺序返回属性名称。
HAS 判断文档是否有指定的属性名
通用语法:
HAS(document, attributeName)
案例:
RETURN HAS( { name: "Jane" }, "age" )
结果:
false
KEEP 只保留文档中的指定属性
通用语法:
KEEP(document, attributeName1, attributeName2, ... attributeNameN)
注:
document(文档):文档/对象
attributeNames(字符串,可重复):任意多个属性名称作为多个参数
LENGTH 求文档的属性的数量
通用语法:
LENGTH(doc)
MERGE 将两个文档合并
通用语法:
MERGE(document1, document2, ... documentN)
案例:
MERGE(
{ "user1": { "name": "Jane" } },
{ "user2": { "name": "Tom" } }
)
结果:
{ "user1": { "name": "Jane" }, "user2": { "name": "Tom" } }
UNSET 从文档中删除指定属性
通用语法:
UNSET(document, attributeName1, attributeName2, ... attributeNameN)
13.4全文函数
FULLTEXT 在集合中查找满足指定属性的属性值的文档
通用语法:
FULLTEXT(coll, attribute, query, limit)
注:
coll(集合):一个集合
attribute(字符串):要搜索的属性的属性名称
query(字符串):全文搜索表达式,如下所述
limit(数量,可选):如果设置为非零值,则结果最多可包含此文档数量
返回docArray(数组):文档数组
案例:
FOR u IN FULLTEXT(users,"name","李四")
RETURN u
要求:
集合需要有全文索引才可以使用
13.5地理函数
DISTANCE 求两个经纬度之间的距离
通用语法:
DISTANCE(latitude1, longitude1, latitude2, longitude2)
案例:
RETURN DISTANCE(52.5163, 13.3777, 50.9322, 6.94)
结果:
[
476918.89688380965
]
GEO_CONTAINS 检查第二个geoJson是否包含于第一个geoJson 3.4引入
通用语法:
GEO_CONTAINS(geoJsonA, geoJsonB)
注:
geoJsonA(对象):第一个GeoJSON对象或坐标数组(按经度,纬度顺序)
geoJsonB(对象):第二个GeoJSON对象或坐标数组(按经度,纬度顺序)
IS_IN_POLYGON 判断坐标是否在多边形内
通用语法:
IS_IN_POLYGON(polygon, latitude, longitude)
注:
polygon(数组):数组的数组,每个数组包含2个元素,以[lat,lon]格式表示多边形的点
latitude(数字):搜索坐标的纬度部分
longitude(数字):搜索坐标的经度部分
13.6数字函数
ABS(value) 绝对值函数
ACOS(value) 反余弦值
ASIN(value) 反正弦值
ATAN(value) 反正切值
ATAN2(y, x) y和x的商的反正切
AVERAGE(numArray) 返回数组中值的平均值
AVG(numArray) 返回数组中值的平均值 (AVERAGE的变形)
CEIL(value) 向上取整
COS(value) 余弦值
SIN(value) 正弦值
TAN(value) 正切值
DEGREES(rad) 将弧度值转换为角度
EXP(value) 返回e的value次方
EXP2(value) 返回2的value次方
FLOOR(value) 向下取整
LOG(value) 以e为底的对数
LOG2(value) 以2为底的对数
LOG10(value) 以10为底的对数
MAX(anyArray) 返回数组中的最大值
MIN(anyArray) 返回数组中的最小值
MEDIAN(numArray) 返回数组的中位数
PERCENTILE(numArray, n, method) 将数组等比排列,并按n进行取值
注:
numArray(数组):数字数组,将忽略空值
n(数字):必须介于0(排除)和100(包括)之间
method(字符串,可选):“等级”(默认)或“插值”
案例一:
RETURN PERCENTILE([1,2,3,4,5],76,"interpolation")
结果:
4.56
案例二:
RETURN PERCENTILE([1,2,3,4,5],76,"rank")
结果:
4
PI() 返回pi
POW(base, exp) 返回base的exp次方
PRODUCT(numArray) 返回数组所有值的乘机 3.7引入
RADIANS(deg) 将角度转换为弧度
RAND() 返回0~1之间的伪随机数
RANGE(start, stop, step) 返回从start到stop,以step为步长的数组
ROUND(value) 对value四舍五入
SQRT(value) 返回算术平方根
STDDEV_POPULATION(numArray) 求数组的标准差
SUM(numArray) 数组求和
VARIANCE_POPULATION(numArray) 返回数组的方差
13.7字符串函数
CONCAT(value1, value2, ... valueN) 字符串拼接
CONCAT_SEPARATOR(separator, value1, value2, ... valueN) 使用分隔符进行拼接
CONTAINS(text, search, returnIndex) 字符串查找
注:
returnIndex(布尔值)
true:返回匹配字符串的位置
false:返回是否找到字符串 true/false
FIND_FIRST(text, search, start, end) 在start和end范围内查找search第 一次出现的位置
FIND_LAST(text, search, start, end) 与上相反
IPV4_FROM_NUMBER(numericAddress) 将IPV4地址值转换为字符串表示形式
案例: 3.7版本引入
IPV4_FROM_NUMBER(2130706433)
结果:
"127.0.0.1"
IPV4_TO_NUMBER(stringAddress) 将IPV4的字符串地址转换为数字表示
3.7.2版本引入
IS_IPV4(value) 判断是否是IPV4的地址
JSON_PARSE(text) 将JSON解析为字符串
JSON_STRINGIFY(value) 要转换为JSON格式的字符串
LEFT(value, n) 返回最左边的n个字符
LIKE(text, search, caseInsensitive) 通配符匹配
注:
caseInsensitive 是否忽略大小写
true:不区分大小写
false :区分大小写
LOWER(value) 将大写字符转换为小写字符
LTRIM(value, chars) 仅去除开头的空格
MD5(text) 对文本进行MD5加密
NGRAM_SIMILARITY(input, target, ngramSize) 返回两个字符串的NGram相似度
注: 3.7版本引入
ngramSize :n值
RANDOM_TOKEN(length) 生产指定长度的伪随机字符串
REGEX_SPLIT(text, splitExpression, caseInsensitive, limit) 使用正则表达式将字符串 分割
REGEX_REPLACE(text, search, replacement, caseInsensitive) 替换被正则表达式检 索到的字符
REVERSE(value) 反转字符串顺序
RIGHT(value, length) 返回字符串最右边的几个字符
RTRIM(value, chars) 仅去除末尾的空格
SHA1(text) 计算文本的SHA1校验和,以十六进制返 回
SPLIT(value, separator, limit) 使用分割符将字符串分割成数组
SUBSTRING(value, offset, length) 返回指定区域内的字符串
TOKENS(input, analyzer) 借助分析器将字符串拆分为数组
TRIM(value, type) 去除字符串头尾的空格
UPPER(value) 将字符串都转换为大写字符
13.8类型转换函数
TO_BOOL(value) 转换为布尔值
注:
null转换为false
数字非0转换为true,0转为false
字符串如果非空为true,反之false
数组始终转换为true(即使为空)
对象/文档始终转换为true
TO_NUMBER(value) 转换为数字
注:
null和false转换为值0
true转换为1
数字保持其原始价值
如果字符串包含数字,则将字符串转换为它们的数字等效项。
不包含任何有效数字表示形式的字符串值将转换为数字0。
将空数组转换为0
将具有一个成员的数组转换TO_NUMBER()为其唯一成员的结果。
具有两个或更多成员的数组将转换为数字0。
对象/文档将转换为数字0。
TO_STRING(value) 转换为字符串
注:
null转换为空字符串""
false转换为字符串“ false”
true转换为字符串“ true”
数字将转换为其字符串表示形式。也可以是科学记数法
TO_ARRAY(value) 转换为数组
注:
null转换为空数组
布尔值,数字和字符串将转换为包含原始值作为其单个元素的数组
数组保留其原始值
对象/文档将转换为包含其属性 值作为数组元素的数组
IS_NULL(value) 检查value是否为null
IS_BOOL(value) 检查value是否为布尔值
IS_NUMBER(value) 检查value是否为数字
IS_STRING(value) 检查value是否为字符串
IS_ARRAY(value) 检查value是否为数组
IS_OBJECT(value) 检查value是否为对象
IS_DATESTRING(str) 检查str是否是日期格式的字符串
IS_KEY(str) 检查str是否是文档的_key
TYPENAME(value) 返回value的数据类型
13.9其他函数
NOT_NULL(alternative, ...) 返回第一个不为null的元素
FIRST_LIST(alternative, ...) 返回第一个数组元素
FIRST_DOCUMENT(value,....) 返回第一个文档元素
CHECK_DOCUMENT(document) 检查是否为有效的文档元素
COLLECTION_COUNT(coll) 确认coll集合中的文档数量
CURRENT_USER() 返回当前用户名称
LENGTH(coll) 返回集合的文档数量
HASH(value) 计算value的hash值
IN_RANGE(value, low, high, includeLow, includeHigh) 检查value是否在范围内
注: 3.7版本引入
值(任何):任意类型的元素
低(任何):所需范围的最小值
高(任意):所需范围的最大值
includeLow(布尔):最小值是否应包含在范围内
includeHigh(布尔):最大值是否应包含在范围
FAIL(reason) 让查询故意失败
SLEEP(seconds) 等待一段时间后再查询
VERSION() 返回服务器版本
- 图的遍历
遍历
通用语法:
[WITH vertexCollection1[, vertexCollection2[, ...vertexCollectionN]]]
FOR vertex[, edge[, path]]
IN [min[..max]]
OUTBOUND|INBOUND|ANY startVertex
GRAPH graphName
[PRUNE pruneCondition]
[OPTIONS options]
分析:
WITH:对于图的遍历是必须的
Collection:遍历中将涉及的顶点集合的列表
FOR:最多发出三个变量:
vertex(对象):遍历中的当前顶点
edge(对象,可选):遍历中的当前边
path(对象,可选):具有两个成员的当前路径的表示形式:
vertices:此路径上所有顶点的数组
edges:此路径上所有边的数组
IN min..max:遍历的最小和最大深度:
min(数字,可选):此查询返回的边和顶点将从最小遍历深度开始。如果未指定,则默认为1。最小可能值为0。
max(数字,可选):最多可遍历最大长度的路径。如果省略,则max默认为min。没有min不能指定max。
OUTBOUND|INBOUND|ANY:沿着遍历中任一方向的传出,传入或边沿;不能用bind参数代替它。
startVertex(string | object):遍历的起点。可以以ID字符串形式或带有属性的文档形式指定_id。其他值将导致警告和空结果。如果指定的文档不存在,则结果也为空,并且没有警告。
GRAPH graphName(字符串):标识命名图的名称。将查找其顶点和边缘集合。图形名称就像一个常规字符串,因此必须用引号引起来。
PRUNE condition(AQL条件,可选,(自版本3.4.5起)):如FILTER语句中一样,将在遍历的每个步骤中提前对其进行评估。此条件的语义如下:
如果将条件评估true为结果,则由于深度限制,可能仍会对其进行后期过滤或忽略。但是,搜索不会从该路径继续进行,也就是说,将以该路径为前缀的结果将不存在。例如:取路径:(A) -> (B) -> (C) 开始A剪枝上B 会导致(A)与(A) -> (B)被有效路径,并(A) -> (B) -> (C) 没有返回,它得到了修剪上B.
如果条件满足,false我们将继续沿着这条道路搜索。PRUNE条件只有一种可能,但是可以包含任意数量的ANDorOR语句。
OPTIONS 选项(对象,可选):用于修改遍历的执行。仅以下属性有效,所有其他属性均被忽略:
bfs(布尔):可选地使用替代的广度优先遍历算法
true –广度优先遍历
false(默认)–深度优先遍历
uniqueVertices(字符串):(可选)确保顶点唯一性
uniqueEdges(字符串):可选地确保边缘唯一性
edgeCollections(字符串|数组):可选地限制遍历可能访问的边缘集合(在v3.7.0中引入)。如果省略,或者指定了空数组,则没有限制。
vertexCollections(字符串|数组):(可选)限制遍历可能访问的顶点集合(在v3.7.0中引入)。如果省略,或者指定了空数组,则没有限制。
parallelism(数字,可选):可选地并行化遍历执行(在v3.7.1中引入)。如果省略或将其设置为1,则遍历执行不会并行化。如果将其设置为大于的值1,则最多可以使用许多工作线程来并行执行遍历。该值受目标计算机上可用内核数的限制。
- 数组运算符
数组扩展符 [*]
将[*]运算符与数组变量一起使用将迭代数组中的所有元素,从而允许访问每个元素的特定属性。要求扩展变量是一个数组。[*] 运算符的结果再次是一个数组。
数组收敛符 [**]
为了折叠(或展平)嵌套数组中的结果,AQL提供了[**] 运算符。它的工作方式类似于[*]运算符,但同时会折叠嵌套数组。
内联表达式
内联表达式可以按照阵列的扩展和收敛操作符 [* ...],[** ...]结合FILTER,LIMIT和RETURN 关键字一起出现,起到过滤的作用。如果它们被组合使用必须以FILTER,LIMIT,RETURN的顺序出现,并且只能出现一次:
通用语法:
anyArray[* FILTER conditions LIMIT skip,limit RETURN 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)
]
}
内联过滤器
案例:
FOR u IN users
RETURN { name: u.name, friends: u.friends[* FILTER CURRENT.age > u.age].name }
在扩展符内仅使用FILTER
内联限制
案例:
FOR u IN users
RETURN { name: u.name, friends: u.friends[* LIMIT 1].name }
在扩展符内仅使用LIMIT
内联投影
案例:
FOR u IN users
RETURN u.friends[* RETURN CONCAT(CURRENT.name, " is a friend of ", u.name)]
在扩展符内仅使用RETURN
ArangoDB自学笔记(万字!!全!!)相关推荐
- 基于Java机器学习自学笔记(第81-87天:CNN卷积神经网络的入门到全代码编写)
注意:本篇为50天后的Java自学笔记扩充,内容不再是基础数据结构内容而是机器学习中的各种经典算法.这部分博客更侧重于笔记以方便自己的理解,自我知识的输出明显减少,若有错误欢迎指正! 目录 1. CN ...
- 程序阅读_全面详解LTE:MATLAB建模仿真与实现_自学笔记(1)调制与编码_程序阅读
程序阅读_全面详解LTE:MATLAB建模仿真与实现_自学笔记(1)调制与编码_程序阅读 在粗浅地掌握了LTE知识后,从今天开始对<全面详解LTE:MATLAB建模仿真与实现>一书的学习. ...
- Python 自学笔记----1.1实例与封装
Python 自学笔记----1.1实例与封装 背景描述 封装 类 实例 总结 代码地址 感悟 背景描述 初次了解了类与对象后,就可以深入学习一些面向对象的特性了:封装,继承,多态之 封装 类 首先还 ...
- 基于 Java 机器学习自学笔记 (第61-62天:ID3决策树)
注意:本篇为50天后的Java自学笔记扩充,内容不再是基础数据结构内容而是机器学习中的各种经典算法.这部分博客更侧重于笔记以方便自己的理解,自我知识的输出明显减少,若有错误欢迎指正! 目录 一.关于决 ...
- pytorch自学笔记
pytorch和tensorflow是机器学习的两大框架,上一篇帖子已经完整梳理了TensorFlow自学的知识点,这一篇把自学pytorch的知识点也整理下来,内容参考了网上很多帖子,不一一引用了, ...
- Python自学笔记9:实操案例六(千年虫,购物流程)
Python自学笔记9:实操案例六(千年虫,购物流程) 网课传送门:第155,156讲,https://www.bilibili.com/video/BV1Sw411Z779?p=155 1.千年虫 ...
- Spring框架自学笔记
Spring框架自学笔记 第一章 简介 Spring是一套建筑标准,比如承重标准.丈量标准,通风标准等,并规范了结构:框架式结构,浇筑式结构,且定义了建筑的每个组成部分名字与接口,比如电力系统的接口是 ...
- PS零基础自学笔记:PS制作伤痕、制作UI图标,老师推荐的一些链接
PS零基础自学笔记:PS制作伤痕.换头 交互设计导论的上机和艺术设计基础换汤不换药,也是搞设计,只不过这次不是Xd,是PS粉墨登场······ 1.PS制作伤痕 https://zhidao.baid ...
- 信息系统项目管理师-自学笔记
软考-信息系统项目管理自学笔记 感谢卢海强老师编写时间2021-06-01 09:39:21 选择说明: 第一章,选择题大约占20分,要看教材的120页左右第2.4-12(项目管理).16(变更).2 ...
最新文章
- Red Hat 5.8 CentOS 6.5 共用 输入法
- 野火linux核心板原理图,野火_f429挑战者_核心板_原理图_v2 1.pdf
- C++析构函数不能失败的4个理由
- centos下rmp包离线下载
- python函数映射教学,Python 序列与映射的解包操作
- [转]locate命令的使用
- safari 获取视频流_如何在Safari中将RSS feed和社交媒体合并为一个流
- 【WPF学习】第四十九章 基本动画
- 《分析服务从入门到精通读书笔记》第四章、创建父子维度(7)
- 同步 Github fork 分支
- 已安装 SQL Server 2005 Express 工具。若要继续,请删除 SQL Server 2005 Express 工具
- Java jdk下载安装与配置及其不同版本jdk切换
- 黑马49期 day06-mysql入门(对照视频整理的一份笔记--有改动)
- 数学分析对计算机有帮助吗,计算机辅助数学分析教学的好处
- 中国31省 5G网速 排名!
- javaScript面试高频技术点(多为原生基础+框架集合)
- 电脑版微信小程序全屏显示方法,手机横屏方法。
- 【考】数据库原理与技术 数据查询
- 计算机等级考试一级在线模拟,全国计算机等级考试一级模拟试题1
- python语言玫瑰花_Python 玫瑰花绘制