该文档主要是翻译自ArangoDB的官方文档
AQL语法
查询类型,空白,注释,关键字和AQL语言中的名称解释
查询类型
一个AQL的查询必须要么返回一个结果(使用RETURN关键字),要么执行一个数据修改操作(使用INSERT,UPDATE,REPLACE,REMOVE或UPSERT关键字)。如果AQL解析器在一个查询中检测到多个数据修改操作,或者它无法确定查询是数据检索还是修改操作,将返回一个错误。
AQL只允许一个查询在单个查询字符串中,因此,不支持像SQL那样使用分号;来分隔多个查询语句是不允许的。
这意味着每次只能执行一个查询操作,如果有多个查询需要执行,您需要对每个查询单独调用执行方法或者在应用层进行逻辑处理。
const db = require('@arangodb').db;
// 单独执行两个查询
let query1Result = db._query('FOR u IN users RETURN u');
let query2Result = db._query('FOR p IN posts RETURN p');
而不是像在SQL中那样写成一个字符串:
-- SQL风格的示例(在AQL中无效)
SELECT * FROM users; SELECT * FROM posts;
空白
空白(空白,回车,换行,制表符)可以在查询文本中用来增加可读性。Tokens必须用任意数量的空白隔开。在字符串或名称中,如果希望保留空白,必须用引号将其包含在内。
注释
注释可以嵌入到查询中的任何位置。AQL解析器将忽略包含在注释中的文本。
多行注释不能嵌套,也就是说,后续注释的开始必须在注释的结束之后,否则将被忽略。
AQL支持两种类型的注释:
单行注释:双斜杠开头,结束于行的末尾或查询字符串的末尾(以先到者为准)
多行注释:这些以斜杠/和星号开始,以星号和斜杠/结束。它们可以跨多行,可以包含任意数量的行。
// 单行注释
/* 多行
注释 */
关键字
在顶层,AQL提供了以下高级操作:
操作 | 描述 |
---|---|
FOR | 数组迭代 |
RETURN | 结果返回 |
FILTER | 非视图的结果筛选 |
SEARCH | 视图的结果筛选 |
SORT | 结果排序 |
LIMIT | 结果切片 |
LET | 变量赋值 |
COLLECT | 结果聚合 |
WINDOW | 聚合相关行 |
INSERT | 插入新文档 |
UPDATE | (部分)更新已有的文档 |
REPLACE | 替换已有的文档 |
REMOVE | 移除已有的文档 |
UPSERT | 插入新文档,如果存在则更新 |
WITH | 集合声明 |
每个操作可以以关键字形式在查询中使用。一个AQL查询通常由多个这些操作组成。
一个AQL查询可能如下所示:
FOR u IN users
FILTER u.type == "newbie" && u.active == true
RETURN u.name
在这个例子中,术语FOR,FILTER和RETURN是根据它们的名字来确定它们的高级操作。这些术语也是关键字,在语言中具有特殊含义。
查询解析器将根据关键字名字来确定它们的高级操作。这意味着关键字只能在特定位置使用,并且所有关键字的单词都作为保留字,不能用在其他地方。
例如,无引号字符串(标识符)的关键字不能用作集合或属性名称。如果你需要在集合或者属性中使用与关键字相同的名称,则需要在查询中对集合或属性名进行引号处理。参见Names
关键字不区分大小写,这意味着它们可以在查询中以小写、大写或混合大小写指定。在本文档中,所有关键字都用大写书写,以使它们与其他查询部分区分开来。
除了更高级别的操作关键字之外,还有更多的关键字。在ArangoDB的未来版本中可能会添加其他关键字。关键字的完整列表当前为:
- AGGREGATE
- ALL
- ALL_SHORTEST_PATHS
- AND
- ANY
- ASC
- COLLECT
- DESC
- DISTINCT
- FALSE
- FILTER
- FOR
- GRAPH
- IN
- INBOUND
- INSERT
- INTO
- K_PATHS
- K_SHORTEST_PATHS
- LET
- LIKE
- LIMIT
- NONE
- NOT
- NULL
- OR
- OUTBOUND
- REMOVE
- REPLACE
- RETURN
- SHORTEST_PATH
- SORT
- TRUE
- UPDATE
- UPSERT
- WINDOW
- WITH
除此之外,语言结构中使用的一些单词不是保留关键字。您可以将它们用作集合或属性名称,而不必引用它们。查询解析器可以根据上下文将它们标识为类似关键字
- KEEP – COLLECT操作变体
- COUNT (WITH COUNT INTO) – COLLECT操作变体
- OPTIONS – FOR / Graph Traversal / SEARCH / COLLECT / INSERT / UPDATE / REPLACE / UPSERT / REMOVE operation
- PRUNE – 图谱遍历,FOR操作变体
- SEARCH – 搜索操作
- TO – 最短路径/所有最短路径/k最短路径/k路径图遍历
最后,还有特殊的变量,它们只在特定上下文中可用。它们区分大小写:
- CURRENT – 在数组内联表达式中可用
- NEW – 在INSERT/UPDATE/REPLACE/UPSERT操作后可用
- OLD – 在UPDATE/REPLACE/UPSERT/REMOVE操作后可用
如果您在同一作用域中定义了一个具有相同名称的变量,那么它的值将是并保持在您设置的值。因此,如果您想访问特殊的变量值,则需要避免为自己的变量使用这些名称。
命名
通常,名称用于AQL查询中的以下内容:
- 集合
- 属性
- 变量
- 函数
AQL中的名称总是区分大小写。集合/视图名称支持的最大长度为256字节。变量名称可以更长,但不鼓励使用。
关键字不能用于名称。如果确实需要使用保留关键字作为名称,则必须将其用反引号或正引号引起来。这被称为引用。
FOR doc IN `filter`
RETURN doc.`sort`
// 由于使用了反引号,filter和sort被视为名称,而不是关键字。
你也可以使用正引号
FOR f IN ´filter´
RETURN f.´sort´
您可以使用括号表示法进行属性访问来替代引号:
FOR f IN `filter`
RETURN f["sort"]
sort是一个引号中的字符串,因此与保留关键字不冲突。
如果名称中包含某些字符(如连字符减号(-)),即AQL中的运算符使用这些字符,则也需要使用引号:
LET `my-var` = 42
集合命名
通常可以在查询中按原样使用集合名称。如果集合恰好与关键字具有相同的名称,则该名称必须包含在后向记号或前向记号中。
如果集合名称中包含连字符减号(-)等特殊字符,则还需要用引号进行标记:
FOR doc IN my-coll
RETURN doc
这个集合名称"my-coll"中有一个连字符减号,但是"-"是一个AQL中的算术运算符减法。为了正确引用集合,必须使用反引号。
如果使用扩展的集合和视图名称(–database.extended-names启动选项),它们可能包含空格或非ASCII字符,如日语或阿拉伯语字母、表情符号、带重音的字母以及其他UTF-8字符。在这些情况下也需要引号:
FOR doc IN ´🥑~колекція =)´
RETURN doc
集合名称包含使用扩展命名约束所允许的字符,并用正向记号引用。
请注意,集合不可能用"或’引用名称,因为它们不能是引号中的字符串文字。
有关集合的命名约束的信息,请参见集合名称
属性命名
引用集合中文档的属性时,必须使用完全限定的属性名称。这是因为一个查询中可能使用多个属性名称不明确的集合。为了避免任何歧义,不允许引用不合格的属性名称。
另请参见属性名称的命名限制
FOR u IN users
FOR f IN friends
FILTER u.active == true && f.active == true && u.id == f.userId
RETURN u.name
在上面的示例中,属性名称active、name、id和userId使用它们所属的集合名称(分别为u和f)进行限定。
变量命名
AQL允许您将值分配给查询中的其他变量。所有被赋值的变量都必须具有在查询上下文中唯一的名称。
FOR u IN users
LET friends = u.friends
RETURN { "name" : u.name, "friends" : friends }
在上面的查询中,users是一个集合名称,u和friends都是变量名称。这是因为FOR和LET运算需要目标变量来存储它们的中间结果。
变量名称应与同一查询中使用的任何集合名称的名称不同,以避免被隐藏,这可能会使具有相同名称的集合在变量分配后无法在查询中访问:
LET users = []
FOR u IN users // 迭代"users"变量,而不是"users"集合
RETURN u
变量名中允许的字符包括字母a到z(大写和小写)、数字0到9、下划线(_)符号和美元($)符号。变量名不能以数字开头。如果变量名以一个或多个下划线字符开头,则下划线后面必须至少跟一个字母(a-z或a-z)。美元符号只能用作变量名的第一个字符,并且后面必须跟一个字母。