@ -1,293 +0,0 @@ | |||
# for语法 | |||
一般语法 | |||
FOR variableName IN expression | |||
图遍历 | |||
FOR vertexVariableName, edgeVariableName, pathVariableName IN traversalExpression | |||
视图 特殊关键字 | |||
FOR variableName IN viewName SEARCH searchExpression | |||
需要注意 视图不能用作遍历中的边集合 | |||
FOR v IN 1..3 ANY startVertex viewName /* 错误的用法 */ | |||
选项 对于集合和视图,该FOR构造支持可选的OPTIONS 后缀以修改行为。通用语法为: | |||
FOR variableName IN expression OPTIONS {option: value, ...} | |||
示例 | |||
表达式返回的每个数组元素仅被访问一次。在所有情况下,表达式都必须返回一个数组。空数组也是允许的。当前数组元素可用于由variableName指定的变量中的进一步处理。 | |||
FOR u IN users | |||
RETURN u | |||
这将遍历数组用户中的所有元素(注意:在这种情况下,此数组由名为“ users”的集合中的所有文档组成),并使当前数组元素在变量u中可用。在此示例中,不对u进行修改,而只是使用RETURN关键字将其推入结果中。 | |||
注意:如此处所示,在基于集合的数组上进行迭代时,除非使用SORT 语句定义了明确的排序顺序,否则文档的顺序是不确定的。 | |||
引入的变量在关闭放置FOR范围之前一直可用FOR。 | |||
另一个示例使用静态声明的值数组进行迭代: | |||
FOR year IN [ 2011, 2012, 2013 ] | |||
RETURN { "year" : year, "isLeapYear" : year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) } | |||
FOR也允许嵌套多个语句。当FOR语句嵌套时,FOR 将创建由各个语句返回的数组元素的叉积。 | |||
FOR u IN users | |||
FOR l IN locations | |||
RETURN { "user" : u, "location" : l } | |||
索引提示 | |||
对于集合,通过此内联选项机制提供了索引提示。提示可以两种不同的格式指定。 | |||
第一个格式选项是最简单的,只有一个索引名称。对于许多情况,这应该足够了。只要有可能在该FOR循环中使用索引的选择,优化器就会首先检查是否可以使用指定的索引。 | |||
如果是这样,它将使用它,而不管它通常是否使用其他索引。如果它不能使用该索引,则它将退回到其正常逻辑以选择另一个索引。 | |||
如果forceIndexHint: true指定了可选参数,那么它将不会回退,而是会产生错误。 | |||
OPTIONS {indexHint: 'byName'[, forceIndexHint: <boolean>]} | |||
第二个是按优先顺序排列的索引名称数组。以这种方式指定时,优化器的行为将与上述相同,但是将按照给定的顺序检查每个指定索引的可行性,并退回其正常逻辑或仅在未指定指定条件时失败指标是可行的。 | |||
OPTIONS {indexHint: ['byName', 'byColor'][, forceIndexHint: <boolean>]} | |||
# return语法 | |||
该RETURN语句可用于产生查询结果。必须RETURN在数据选择查询的每个块的末尾指定一条语句,否则查询结果将是不确定的。RETURN在数据修改查询的主级别使用 是可选的。 | |||
一般语法为RETURN: | |||
RETURN expression or RETURN DISTINCT(如果查询的顶层没有FOR 循环,则不允许在查询的顶层。) | |||
另外 arangodb3.3开始 return distinct 将不会改变其应用结果的顺序 | |||
注意:RETURN将关闭当前作用域并消除其中的所有局部变量。在处理子查询时,记住这一点很重要。 | |||
# filter语法 | |||
一般语法 | |||
FILTER expression | |||
expression必须是评估为false或true的条件。如果条件结果为false,则将跳过当前元素,因此将不对其进行进一步处理,也不将其作为结果的一部分。 | |||
如果条件为true,则不跳过当前元素,可以对其进行进一步处理。有关条件中可以使用的比较运算符,逻辑运算符等的列表,请参见运算符。\ | |||
另外注意filter的位置 他会影响查询的结果 | |||
# search语法 | |||
该SEARCH关键字开始语言结构类型为ArangoSearch的过滤器视图。从概念上讲,视图只是另一个文档数据源,类似于数组或文档/边缘集合,您可以在其上使用AQL中的FOR操作进行迭代: | |||
可选SEARCH操作提供以下功能: | |||
1. 根据AQL布尔表达式和函数过滤文档 | |||
2. 匹配位于由快速索引支持的不同集合中的文档 | |||
3. 根据每个文档与搜索条件的匹配程度对结果集进行排序 | |||
一般语法 | |||
FOR doc IN viewName | |||
SEARCH expression OPTIONS {…} | |||
... | |||
SEARCH与相比FILTER,该语句被视为FOR操作的一部分 ,而不是单独的语句。它不能随意放置在查询中,也不能多次放置在FOR循环体内。 | |||
FOR ... IN必须紧随其后的是View的名称,而不是集合的名称。该SEARCH操作必须遵循接下来,其他操作之前SEARCH,如FILTER, | |||
COLLECT等没有在这个位置上允许的。SEARCH在表达式之后,可以进行后续操作, 但包括SORT根据ArangoSearch View计算的排名值对搜索结果进行排序。 | |||
expression必须是ArangoSearch表达式。在搜索和排序阶段,ArangoSearch的全部功能都通过特殊的ArangoSearch功能加以利用和公开。最重要的是,支持常见的AQL运算符: | |||
AND, && | |||
OR, || | |||
NOT, ! | |||
== | |||
<= | |||
>= | |||
< | |||
> | |||
!= | |||
IN (数组或范围),也 NOT IN | |||
ArangoSearch不会考虑字母的字母顺序,即针对视图的SEARCH操作中的范围查询将不会遵循已定义的Analyzer语言环境或服务器语言(启动选项--default-language)的语言规则!另请参阅已知问题。 | |||
FOR doc IN viewName | |||
SEARCH ANALYZER(doc.text == "quick" OR doc.text == "brown", "text_en") | |||
RETURN doc | |||
支持数组比较运算符(在v3.6.0中引入): | |||
LET tokens = TOKENS("some input", "text_en") // ["some", "input"] | |||
FOR doc IN myView SEARCH tokens ALL IN doc.title RETURN doc // dynamic conjunction | |||
FOR doc IN myView SEARCH tokens ANY IN doc.title RETURN doc // dynamic disjunction | |||
FOR doc IN myView SEARCH tokens NONE IN doc.title RETURN doc // dynamic negation | |||
FOR doc IN myView SEARCH tokens ALL > doc.title RETURN doc // dynamic conjunction with comparison | |||
FOR doc IN myView SEARCH tokens ANY <= doc.title RETURN doc // dynamic disjunction with comparison | |||
请注意,不支持内联表达式和其他一些功能 SEARCH。如果表达式无效,服务器将引发查询错误。 | |||
所述OPTIONS关键字和一个对象可以任选地按照搜索表达式来设置搜索选项。 | |||
处理非索引字段固定链接 | |||
未配置为由视图索引的文档属性被SEARCH视为不存在。这会影响仅从视图发出的文档的测试。 | |||
如果需要,可以使用特殊的includeAllFields View属性为源文档的所有(子)字段建立索引。 | |||
# sort语法 | |||
SORT expression direction(ASC or DESC)(默认升序ASC) | |||
# limit语法 | |||
LIMIT count | |||
LIMIT offset, count | |||
# let语法 | |||
该LET语句可用于为变量分配任意值。然后将该变量引入LET放置该语句的作用域中。 | |||
通用语法为: | |||
LET variableName = expression | |||
变量在AQL中是不可变的,这意味着它们不能重新分配: | |||
# collect语法 | |||
COLLECT关键字可用来组由一个或多个基团的标准阵列。 | |||
该COLLECT语句将消除当前范围内的所有局部变量。之后,COLLECT只有由COLLECT自身引入的变量才可用。 | |||
操作有几种语法变体COLLECT: | |||
COLLECT variableName = expression | |||
COLLECT variableName = expression INTO groupsVariable | |||
COLLECT variableName = expression INTO groupsVariable = projectionExpression | |||
COLLECT variableName = expression INTO groupsVariable KEEP keepVariable | |||
COLLECT variableName = expression WITH COUNT INTO countVariable | |||
COLLECT variableName = expression AGGREGATE variableName = aggregateExpression | |||
COLLECT variableName = expression AGGREGATE variableName = aggregateExpression INTO groupsVariable | |||
COLLECT AGGREGATE variableName = aggregateExpression | |||
COLLECT AGGREGATE variableName = aggregateExpression INTO groupsVariable | |||
COLLECT WITH COUNT INTO countVariable | |||
所有变体都可以选择以OPTIONS { … }子句结尾。 | |||
# remove语法 | |||
REMOVE keyExpression IN collection options | |||
REMOVE keyExpression IN collection options RETURN OLD | |||
# udpate语法 | |||
更新操作的两种语法是: | |||
UPDATE document IN collection options | |||
UPDATE keyExpression WITH document IN collection options | |||
UPDATE document IN collection options RETURN OLD | |||
UPDATE document IN collection options RETURN NEW | |||
UPDATE keyExpression WITH document IN collection options RETURN OLD | |||
UPDATE keyExpression WITH document IN collection options RETURN NEW、 | |||
# replace语法 | |||
REPLACE document IN collection options | |||
REPLACE keyExpression WITH document IN collection options | |||
REPLACE document IN collection options RETURN OLD | |||
REPLACE document IN collection options RETURN NEW | |||
REPLACE keyExpression WITH document IN collection options RETURN OLD | |||
REPLACE keyExpression WITH document IN collection options RETURN NEW | |||
以下查询使用NEW伪值返回替换的文档(不包含某些系统属性): | |||
FOR u IN users | |||
REPLACE u WITH { value: "test" } IN users | |||
LET replaced = NEW | |||
RETURN UNSET(replaced, '_key', '_id', '_rev') | |||
# insert语法 | |||
INSERT document INTO collection [ OPTIONS options ] | |||
INSERT document INTO collection RETURN NEW | |||
IN关键字可以代替INTO并具有相同的含义。 | |||
# upsert语法 | |||
UPSERT searchExpression INSERT insertExpression UPDATE updateExpression IN collection options | |||
UPSERT searchExpression INSERT insertExpression REPLACE updateExpression IN collection options | |||
当使用UPDATEupsert操作的变体时,找到的文档将被部分更新,这意味着仅updateExpression中指定的属性将被更新或添加。使用REPLACEupsert 的变体时,现有文档将被updateExpression的上下文替换。 | |||
更新文档将使用服务器生成的值来修改文档的修订号。系统属性_id,_key和_rev无法更新,_from和_to可以更新。 | |||
# with语法 | |||
WITH managers | |||
FOR v, e, p IN OUTBOUND 'users/1' usersHaveManagers | |||
RETURN { v, e, p } | |||
插入文档 | |||
语法是INSERT document INTO collectionName。该文档是一个对象,您可以从JavaScript或JSON中了解它,它由属性键和值对组成。 | |||
属性键周围的引号在AQL中是可选的。键总是字符序列(字符串),而属性值可以有不同的类型: | |||
空值 | |||
布尔值(true,false) | |||
数字(整数和浮点数) | |||
串 | |||
排列 | |||
宾语 | |||
该LET关键字定义一个带有名称数据的变量和一个对象数组作为值,因此LET variableName = valueExpression表达式是一个文字数组定义[ {...}, {...}, ... ]。 | |||
FOR variableName IN expression用于迭代数据数组的每个元素 。在每个循环中,将一个元素分配给变量d。然后在INSERT语句中使用此变量而不是文字对象定义。基本上是做什么的: | |||
INSERT { | |||
"name": "Robert", | |||
"surname": "Baratheon", | |||
"alive": false, | |||
"traits": ["A","H","C"] | |||
} INTO Characters | |||
INSERT { | |||
"name": "Jaime", | |||
"surname": "Lannister", | |||
"alive": true, | |||
"age": 36, | |||
"traits": ["A","F","B"] | |||
} INTO Characters | |||
... | |||
注意:AQL不允许INSERT在单个查询中针对同一集合的多个操作。然而, 允许它作为FOR循环体,插入多个文档,就像我们对上面的查询所做的那样。 | |||
FOR c IN Characters_1 RETURN c | |||
循环的语法是FOR variableName IN collectionName。对于集合中的每个文档,将为c分配一个文档,然后根据循环体返回该文档。查询返回我们先前存储的所有字符。 | |||
该文档包含我们存储的四个属性,以及数据库系统添加的另外三个属性。每个文档都需要一个唯一的文档_key,用于在集合中标识它。它_id是计算属性,集合名称, | |||
正斜杠/和文档键的串联。它唯一标识数据库中的文档。_rev是系统管理的修订版ID。 | |||
用户可以在创建文档时提供文档键,也可以自动分配唯一值。它以后不能改变。以下划线开头的所有三个系统属性_都是只读的。 | |||
我们可以使用文档密钥或文档ID在AQL函数的帮助下检索特定文档DOCUMENT() | |||
更新文档 | |||
UPDATE documentKey WITH object IN collectionName l列出的属性更新指定的文档(存在则添加它们) | |||
要更新整个文档 整个用replace | |||
可以用循环 更新或者替换属性 | |||
FOR c IN Character | |||
UPDATE c with {swason: 1} IN Character | |||
删除文件 | |||
要从集合中删除文档 执行 REMOVE | |||
REMOVE "201213" IN Character | |||
FOR C IN Characters | |||
REMOVE c IN Characters | |||
匹配条件 | |||
为了查找满足条件的文档 FILTER AQL | |||
FOR c IN Characters | |||
FILTER c.age >= 12 | |||
RETURN c.name | |||
多种条件 | |||
FOR c IN Characters | |||
FILTER c.age 《 13 | |||
FILTER c.age != null | |||
RETURN {name: c.name, age: c.age} 可以用AND运算符 | |||
同时也有OR运算符 | |||
限制结果计数 | |||
FOR c IN Characters_1 | |||
LIMIT 5 | |||
RETURN c.name | |||
FOR c IN Characters | |||
LIMIT 2,5 | |||
RETURN c.name | |||
@ -1,8 +0,0 @@ | |||
Start ArangoDB shell client: | |||
> /usr/bin/arangosh | |||
Start ArangoDB service: | |||
> systemctl start arangodb3.service | |||
Enable ArangoDB service: | |||
> systemctl enable arangodb3.service |
@ -1,44 +0,0 @@ | |||
数据库名称 | |||
ArangoDB将始终从名为_system的默认数据库启动。用户可以在ArangoDB中创建其他数据库,前提是数据库名称符合以下约束: | |||
数据库名称只能由字母a到z(允许大小写),数字0到9以及下划线(_)或破折号(-)符号组成。这也意味着,任何非ASCII数据库名称都不是允许的 | |||
数据库名称必须始终以字母开头。下划线开头的数据库名称被认为是系统数据库,用户不应创建或删除这些名称 | |||
数据库名称允许的最大长度为64个字节 | |||
数据库名称区分大小写 | |||
集合名称和视图名称 | |||
用户可以根据需要选择其集合和视图的名称,前提是不违反以下命名约束: | |||
名称只能由字母a到z(大小写),数字0到9以及下划线(_)或破折号(-)符号组成。这也意味着不允许使用任何非ASCII名称。 | |||
视图名称必须始终以字母开头。 | |||
用户定义的集合名称必须始终以字母开头。系统集合名称必须以下划线开头。 | |||
所有以下划线开头的集合名称均被视为仅用于ArangoDB内部使用的系统集合。最终用户不应将系统集合名称用于自己的集合。 | |||
名称的最大允许长度为256个字节。 | |||
集合名称和视图名称区分大小写。 | |||
文档_key | |||
用户可以为保存的文档定义自己的密钥。文档密钥将与文档一起保存在_key属性中。用户可以根据需要选择键值,只要这些键值符合以下限制: | |||
键必须是字符串值。不允许使用数字键,但是可以将任何数字值放入字符串中,然后用作文档键。 | |||
密钥必须至少为1个字节,最大为254个字节。指定时不允许使用空键(尽管从文档中完全省略_key属性可能是有效的 ) | |||
它必须由字母az(小写或大写),数字0-9或以下任何标点字符组成: _ - : . @ ( ) + , = ; $ ! * ' % | |||
键值内不能使用任何其他字符,尤其是多字节UTF-8序列,空格或标点字符 | |||
该密钥在使用的集合中必须唯一 | |||
键区分大小写,即myKey和MyKEY被认为是不同的键。 | |||
创建新文档时,指定文档密钥是可选的。如果用户未指定文档密钥,则ArangoDB将自己创建文档密钥,因为每个文档都必须具有密钥。 | |||
除上述限制外,无法保证自动生成的文档密钥的格式和模式。因此,客户应将自动生成的文档密钥视为不透明的值,而不应依赖于其格式。 | |||
生成密钥的当前格式是包含数字的字符串。从后面生成的_key值将包含比之前生成的_key值更高的数字的意义上,数字值反映了时间顺序。但是服务器将生成的确切值是不可预测的。请注意,如果按_key属性排序,则将使用字符串比较,这意味着"100"小于"99"。 | |||
属性名称 | |||
用户可以根据需要选择文档属性的属性名称,前提是不违反以下属性命名约束: | |||
以下划线开头的属性名称被视为ArangoDB内部使用的系统属性。此类属性名称已被ArangoDB用于特殊目的: | |||
_id用于包含文档的句柄 | |||
_key用于包含文档的用户定义键 | |||
_rev用于包含文档的修订号 | |||
在边缘收藏中, | |||
_from | |||
_to | |||
属性用于引用其他文档。 | |||
将来可能会添加更多系统属性,恕不另行通知,因此最终用户应尽量避免使用以下划线开头的自己的属性名称。 | |||
从理论上讲,属性名称可以根据需要包括标点符号和特殊字符,前提是该名称是有效的UTF-8字符串。为了获得最大的可移植性,应避免使用特殊字符。例如,属性名称可能包含点符号,但是点在JavaScript和AQL中具有特殊含义,因此当以这些语言中的一种使用此类属性名称时,最终用户需要用引号引起来。总的来说,最好使用不需要使用所有语言进行任何引用/转义的属性名称。如果属性映射到客户端的对象成员,则包括客户端使用的语言(例如Ruby,PHP)。 | |||
当在AQL查询中使用属性名称时,以加号(@)开头的属性名称必须用反引号括起来,以区别绑定变量。因此,我们建议您不要使用以at-标记开头的属性,尽管它们在正确使用后仍然可以使用。 | |||
ArangoDB不对属性名称实施长度限制。但是,长属性名称可能会在结果集中使用更多的内存等。因此,不建议使用长属性名称。 | |||
属性名称区分大小写。 | |||
不允许使用名称为空(字符串为空)的属性。 |
@ -1,22 +0,0 @@ | |||
类型和值顺序 | |||
在检查是否相等或不相等或确定值的排序顺序时,AQL使用确定性算法,该算法同时考虑数据类型和实际值。 | |||
比较的操作数首先按其数据类型进行比较,如果操作数具有相同的数据类型,则仅按其数据值进行比较。 | |||
比较数据类型时,使用以下类型顺序: | |||
null < bool < number < string < array/list < object/document | |||
这意味着null是AQL中最小的类型,而document是具有最高顺序的类型。如果比较的操作数具有不同的类型,则确定比较结果并完成比较。 | |||
如果两个比较的操作数具有相同的数据类型,则将比较操作数的值。对于基本类型(null,布尔值,数字和字符串),结果定义如下: | |||
null:null等于null | |||
布尔值:false小于true | |||
数字:数值按基数排序 | |||
字符串:使用本地化比较对字符串值进行排序,使用配置的 服务器语言 根据该语言的字母顺序规则进行排序 | |||
注意:与SQL不同,可以将null与任何值进行比较,包括null 本身,而不会自动将结果转换为null。 | |||
对于化合物,将应用以下特殊规则: | |||
从第一个元素开始,通过逐个位置比较它们的各个元素来比较两个数组值。对于每个位置,首先比较元素类型。如果类型不相等,则确定比较结果,并且比较结束。如果类型相等,则将比较两个元素的值。如果其中一个数组已完成,而另一个数组在比较位置仍然有一个元素,则将null用作完全遍历数组的元素值。 | |||
如果数组元素本身是复合值(数组或对象/文档),则比较算法将递归检查元素的子值。递归比较元素的子元素。 | |||
通过检查属性名称和值来比较两个对象/文档操作数。首先比较属性名称。在比较属性名称之前,将创建两个操作数的所有属性名称的组合数组,并按字典顺序进行排序。这意味着在比较两个对象/文档时,在对象/文档中声明属性的顺序无关紧要。 | |||
然后遍历组合和排序的属性名称数组,然后从两个比较的操作数中查找相应的属性。如果对象/文档之一不具有具有所寻找名称的属性,则其属性值被视为null。最后,使用前面提到的数据类型和值比较来比较两个对象/文档的属性值。对所有对象/文档属性执行比较,直到明确的比较结果为止。如果找到明确的比较结果,则比较结束。如果没有明确的比较结果,则将两个比较的对象/文档视为相等。 |
@ -1,237 +0,0 @@ | |||
索引基础 | |||
索引允许快速访问文档,前提是在查询中使用了索引属性。尽管ArangoDB自动为某些系统属性建立索引,但用户可以自由地在文档的非系统属性上创建额外的索引。 | |||
可以在集合级别上创建用户定义的索引。可以通过指定索引属性的名称来创建大多数用户定义的索引。一些索引类型只允许索引一个属性(例如全文本索引),而其他索引类型只允许同时索引多个属性。 | |||
通过学习ArangoDB性能课程,学习如何有效地使用不同的索引 。 | |||
该系统属性_id,_key,_from并且_to通过ArangoDB会自动建立索引,而不需要用户为他们创造额外的索引。 _id并且_key被集合的主键 覆盖,_from并且_to被边缘集合的边缘索引自动覆盖。 | |||
使用该系统属性_id在用户定义的索引是不可能的,但索引_key,_rev,_from,和_to是。 | |||
默认情况下,创建新索引是在独占集合锁下完成的。创建索引时,该集合不可用。如果您必须在没有专用维护窗口的实时系统上执行索引创建,那么“前景”索引可能是不可取的。 | |||
对于可能长时间运行的索引创建操作,RocksDB存储引擎还支持在“后台”创建索引。该集合在索引创建期间仍然(大部分)可用,请参阅“ 在后台创建索引 ”部分以获取更多信息。 | |||
ArangoDB提供以下索引类型: | |||
主要指标 | |||
对于每个集合,总会有一个主索引,该主索引是集合中所有文档的文档关键字(_key属性)的持久索引。主索引允许使用_key或_id属性快速选择集合中的文档。在_key或上执行相等查找时,将自动在AQL查询中使用它 _id。 | |||
还有一些专用功能来查找给定的文档,_key或者_id 始终使用主索引的文档: | |||
db.collection.document("<document-key>"); | |||
db._document("<document-id>"); | |||
当对持久性索引进行排序时,主索引可用于范围查询和排序。 | |||
集合的主索引不能删除或更改,也没有创建用户定义的主索引的机制。 | |||
边缘指数 | |||
每个边缘集合还具有一个自动创建的边缘索引。边缘索引可通过文档的_from或_to属性快速访问文档。因此,它可用于快速查找顶点文档之间的连接,并在查询顶点的连接边时调用。 | |||
对边缘集合_from 或_to边缘集合中的值执行相等查找时,会从AQL中使用边缘索引。还有一些专用函数可以找到给定的边_from或边_to值,这些边将始终利用边索引: | |||
db.collection.edges("<from-value>"); | |||
db.collection.edges("<to-value>"); | |||
db.collection.outEdges("<from-value>"); | |||
db.collection.outEdges("<to-value>"); | |||
db.collection.inEdges("<from-value>"); | |||
db.collection.inEdges("<to-value>"); | |||
边缘索引存储所有_from和_to属性的并集。它可以用于相等查找,但不能用于范围查询或排序。将自动为边缘集合创建边缘索引。 | |||
无法创建用户定义的边缘索引。但是,可以在用户定义的索引中自由使用_from和_to属性。 | |||
不能删除或更改边缘索引。 | |||
持久指数 | |||
持久索引是具有持久性的排序索引。存储或更新文档时,索引条目将写入磁盘。这意味着在重新启动服务器或初始加载索引的集合时,不需要从集合数据中重建索引条目。因此,使用持久索引可以减少集合加载时间。 | |||
持久索引类型目前可用于二级索引。这意味着持久性索引当前不能成为集合的唯一索引,因为该集合将始终存在内存中的主索引,并且可能还有更多的索引(例如Edge集合的edge索引)。 | |||
索引实现使用的是RocksDB引擎,它为插入,更新和删除操作提供了对数复杂性。由于持久索引不是内存索引,因此它不像所有内存索引一样将指针存储到主索引中,而是存储文档的主键。为了通过索引值查找通过持久索引检索文档,因此将在主索引中进行额外的O(1)查找以获取实际文档。 | |||
在对持久索引进行排序时,它可以用于点查找,范围查询和排序操作,但前提是必须在查询中提供所有索引属性,或者指定索引属性的最左前缀。 | |||
TTL(生存时间)索引 | |||
ArangoDB提供的TTL索引类型可用于自动从集合中删除过期的文档。 | |||
通过设置expireAfter值并选择包含文档创建日期和时间的单个文档属性来设置TTL索引。文档expireAfter在创建时间后几秒钟后过期。创建时间被指定为数字时间戳(Unix时间戳)或格式的日期字符串YYYY-MM-DDTHH:MM:SS,可以选择使用格式 的小数点后的毫秒数YYYY-MM-DDTHH:MM:SS.MMM和可选的时区偏移量。所有没有时区偏移的日期字符串都将被解释为UTC日期。 | |||
例如,如果expireAfter将设置为600秒(10分钟),并且索引属性为“ creationDate”,则存在以下文档: | |||
{ "creationDate" : 1550165973 } | |||
该文档将使用创建日期时间值索引,该值1550165973将转换为人类可读的date 2019-02-14T17:39:33.000Z。此文档将在时间戳记1550166573(或 2019-02-14T17:49:33.000Z人类可读版本)之后的600秒后过期。 | |||
实际删除过期文件并不一定会立即发生。过期的文档最终将由后台线程删除,该线程定期遍历所有TTL索引并删除过期的文档。可以使用--ttl.frequency 启动选项配置调用此后台线程的频率。 | |||
无法保证何时将完全删除过期的文档,因此查询仍然可以找到并返回已经过期的文档。这些文件最终将在后台线程启动并具有删除过期文档的能力时被删除。但是可以保证,只有超过其到期时间的文档才会被真正删除。 | |||
请注意,自1970年1月1日(Unix时间戳)以来,必须以秒为单位指定index属性的数字日期时间值。要以这种格式从JavaScript计算当前时间戳,可以使用Date.now() / 1000;。要从任意Date实例计算它,有Date.getTime() / 1000。在AQL中,您可以 DATE_NOW() / 1000将任意Unix时间戳(以毫秒为单位)除以1000,以将其转换为秒。 | |||
另外,可以将index属性值指定为date字符串,格式为 YYYY-MM-DDTHH:MM:SS,可选的格式是小数点后的毫秒YYYY-MM-DDTHH:MM:SS.MMM和可选的时区偏移量。所有没有时区偏移的日期字符串都将被解释为UTC日期。 | |||
上面使用datestring属性值的示例文档为 | |||
{ "creationDate" : "2019-02-14T17:39:33.000Z" } | |||
如果index属性不包含数字值或正确的日期字符串,则该文档将不会存储在TTL索引中,因此不会成为过期和删除的候选对象。为索引属性提供非数字值或什至不提供值是防止文档过期和删除的一种受支持方法。 | |||
地理索引 | |||
用户可以在集合中的一个或多个属性上创建其他地理索引。地理索引用于快速找到地球表面的位置。 | |||
地理索引存储二维坐标。它可以在两个单独的文档属性(纬度和经度)上创建,也可以在包含纬度和经度的单个数组属性上创建。纬度和经度必须是数字值。 | |||
地理索引提供了以下操作:查找坐标最接近给定比较坐标的文档,以及查找坐标在围绕比较坐标的指定半径内的文档。 | |||
地理位置索引是通过AQL中的专用功能(简单查询功能)使用的,当在AQL中将SORT或FILTER与距离功能一起使用时,它会隐式应用。否则,它将不会用于其他类型的查询或条件。 | |||
全文索引 | |||
全文索引可用于在文档中查找单词或单词前缀。全文索引只能在单个属性上创建,并且将对文档中包含的具有该属性文本值的所有单词进行索引。仅索引(指定)最小长度的单词。使用libicu提供的单词边界分析来完成单词标记化,该分析考虑了服务器启动时提供的所选语言。单词以小写形式索引。该指数支持完全匹配的查询(满语)和前缀查询,加上基本的逻辑操作,例如 and,or和not用于组合部分结果。 | |||
全文索引是稀疏的,这意味着它只会索引设置了index属性且包含字符串值的文档。此外,索引中仅包含具有可配置的最小长度的单词。 | |||
全文索引通过AQL中的专用功能或简单查询使用,但不会为其他类型的查询或条件启用。 | |||
对于高级全文搜索功能,请考虑ArangoSearch。 | |||
索引属性和子属性 | |||
顶级以及嵌套属性都可以建立索引。对于顶级属性,仅需要属性名称。要为单个字段建立索引,请将具有单个元素(属性键的字符串)的数组传递给sureIndex()方法的fields参数 。要在多个字段上创建组合索引,只需将更多成员添加到fields数组中: | |||
// { name: "Smith", age: 35 } | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "name" ] }) | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "name", "age" ] }) | |||
要索引子属性,请使用点符号指定属性路径: | |||
// { name: {last: "Smith", first: "John" } } | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "name.last" ] }) | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "name.last", "name.first" ] }) | |||
索引数组值 | |||
如果索引属性包含一个数组,则默认情况下,ArangoDB将整个数组存储为索引值。这样就无法通过索引访问数组的各个成员。 | |||
若要使索引将单个数组成员而不是整个数组值插入到索引中,需要为该属性创建一个特殊的数组索引。使用该collection.ensureIndex()函数可以像常规持久性索引一样设置数组索引。为了使持久索引成为数组索引,[*] 在创建索引以及使用IN运算符在AQL查询中进行过滤时,需要扩展索引属性名称。 | |||
以下示例tags在名为的集合中的属性 上创建持久数组索引posts: | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*]" ] }); | |||
db.posts.insert({ tags: [ "foobar", "baz", "quux" ] }); | |||
然后,该数组索引可用于tags通过IN运算符从AQL查询中查找单个值: | |||
FOR doc IN posts | |||
FILTER 'foobar' IN doc.tags | |||
RETURN doc | |||
可以添加数组扩展运算符 [*],但这不是强制性的。您可以使用它来表示已使用数组索引,但是它纯粹是修饰性的: | |||
FOR doc IN posts | |||
FILTER 'foobar' IN doc.tags[*] | |||
RETURN doc | |||
以下FILTER条件将不使用数组索引: | |||
FILTER doc.tags ANY == 'foobar' | |||
FILTER doc.tags ANY IN 'foobar' | |||
FILTER doc.tags IN 'foobar' | |||
FILTER doc.tags == 'foobar' | |||
FILTER 'foobar' == doc.tags | |||
也可以在数组值的子属性上创建索引。如果index属性是一个对象数组,例如: | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*].name" ] }); | |||
db.posts.insert({ tags: [ { name: "foobar" }, { name: "baz" }, { name: "quux" } ] }); | |||
然后,以下查询将使用数组索引(这确实需要 数组扩展运算符): | |||
FOR doc IN posts | |||
FILTER 'foobar' IN doc.tags[*].name | |||
RETURN doc | |||
如果存储的文档中的数组确实包含不具有子属性的元素,则该文档也将被索引为value null,该值在ArangoDB中等于不存在的属性。 | |||
ArangoDB支持使用[*]每个索引属性使用单个运算符来创建数组索引。例如,不支持如下创建索引: | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*].name[*].value" ] }); | |||
数组值在插入数组索引之前将自动进行重复数据删除。例如,如果将以下文档插入到集合中,则重复的数组值bar将仅被插入一次: | |||
db.posts.insert({ tags: [ "foobar", "bar", "bar" ] }); | |||
这样做是为了避免对同一文档重复存储相同索引值,这不会带来任何好处。 | |||
如果将数组索引声明为unique,则会在将数组值插入索引之前对数组值进行重复数据删除,因此上述具有两个相同值的插入操作 bar不一定会失败 | |||
如果索引已经包含该bar值的实例,它将总是失败。但是,如果bar索引中不存在该值,则对数组值进行重复数据删除将实际上导致bar仅插入一次。 | |||
要关闭数组值的重复数据删除,可以将数组索引的重复数据删除属性设置为false。但是,重复数据删除的默认值为true,因此,如果未明确关闭重复数据删除,则会进行重复数据删除。 | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*]" ], deduplicate: false }); | |||
// will fail now | |||
db.posts.insert({ tags: [ "foobar", "bar", "bar" ] }); | |||
如果声明了数组索引,并且您在指定的属性中存储没有数组的文档,则该文档不会插入索引中。因此,以下对象将不被索引: | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*]" ] }); | |||
db.posts.insert({ something: "else" }); | |||
db.posts.insert({ tags: null }); | |||
db.posts.insert({ tags: "this is no array" }); | |||
db.posts.insert({ tags: { content: [1, 2, 3] } }); | |||
数组索引能够索引显式null值。当查询null值时,它将仅返回那些已明确null存储在数组中的文档,而不会返回任何根本没有数组的文档。 | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*]" ] }); | |||
db.posts.insert({tags: null}) // Will not be indexed | |||
db.posts.insert({tags: []}) // Will not be indexed | |||
db.posts.insert({tags: [null]}); // Will be indexed for null | |||
db.posts.insert({tags: [null, 1, 2]}); // Will be indexed for null, 1 and 2 | |||
将数组索引声明为稀疏对索引的数组部分没有影响,这尤其意味着null在稀疏版本中也对显式值进行索引。如果将索引与数组和常规属性组合在一起,则稀疏性将适用于该属性,例如: | |||
db.posts.ensureIndex({ type: "persistent", fields: [ "tags[*]", "name" ], sparse: true }); | |||
db.posts.insert({tags: null, name: "alice"}) // Will not be indexed | |||
db.posts.insert({tags: [], name: "alice"}) // Will not be indexed | |||
db.posts.insert({tags: [1, 2, 3]}) // Will not be indexed | |||
db.posts.insert({tags: [1, 2, 3], name: null}) // Will not be indexed | |||
db.posts.insert({tags: [1, 2, 3], name: "alice"}) | |||
// Will be indexed for [1, "alice"], [2, "alice"], [3, "alice"] | |||
db.posts.insert({tags: [null], name: "bob"}) | |||
// Will be indexed for [null, "bob"] | |||
请注意,仅在查询使用IN操作符对索引属性进行过滤时,使用数组索引的过滤仅在AQL查询中有效。其它比较运算符(==,!=,>,>=,<,<=,ANY,ALL,NONE)不能目前使用阵列的索引。 | |||
顶点中心索引 | |||
如上所述,图形最重要的索引是边缘索引,它索引边缘集合的_from和_to属性。它们提供了对源自或到达给定顶点的所有边的非常快速的访问,这允许快速找到图中顶点的所有邻居。 | |||
在许多情况下,我们希望运行更具体的查询,例如,在给定顶点起源的边中仅查找那些时间戳大于或等于某个日期和时间的边。确切地说,这是通过“以顶点为中心的索引”实现的。从某种意义上讲,它们是每个单个顶点处的边缘集合的局部索引。 | |||
从技术上说,他们在ArangoDB实现为索引,其排序完整边集合首先_from,然后通过其他属性出境遍历,或者先通过_to,然后由其他属性入境遍历。对于在ANY方向上的遍历,需要两个索引,一个索引与_from另一个_to索引作为第一个索引字段。 | |||
例如,如果我们在属性_from和 timestamp边缘集合上有一个持久索引,则可以通过在索引中进行一次范围查找来非常快速地回答上述问题。 | |||
从ArangoDB 3.0开始,可以创建排序索引(类型为“持久”)来索引特殊边缘属性_from或_to 其他属性。从ArangoDB 3.1开始,当FILTER优化器找到适当的语句时,这些将用于图遍历。 | |||
例如,要创建上述类型的顶点中心索引,您只需 | |||
db.edges.ensureIndex({"type":"persistent", "fields": ["_from", "timestamp"]}); | |||
在阿兰戈什。然后,查询如 | |||
FOR v, e, p IN 1..1 OUTBOUND "V/1" edges | |||
FILTER e.timestamp >= "2018-07-09" | |||
RETURN p | |||
如果有许多来自顶点的边,"V/1"但是只有少数带有最近时间戳记的边,则速度会更快。请注意,即使顶点中心索引实际上可能更快,优化器也可能会基于估计的成本而选择默认边缘索引而不是顶点中心索引。对于高度连接的图形和RocksDB存储引擎,更可能选择以顶点为中心的索引。 | |||
在后台创建索引 | |||
在v3.5.0中引入 | |||
默认情况下,创建新索引是在独占集合锁下完成的。这意味着只要创建索引,集合(或相应的分片)就不可用于写操作。如果您必须在没有专用维护窗口的实时系统上执行索引创建,那么“前景”索引可能是不可取的。 | |||
索引也可以在“后台”中创建,而不在整个索引创建过程中使用排他锁。该集合基本上保持可用,因此在创建索引时其他CRUD操作可以在该集合上运行。这可以通过在创建索引时设置inBackground属性来实现。 | |||
要在arangosh中在后台创建索引,只需指定inBackground: true,如以下示例所示: | |||
// create the persistent index in the background | |||
db.collection.ensureIndex({ type: "persistent", fields: [ "value" ], unique: false, inBackground: true }); | |||
db.collection.ensureIndex({ type: "persistent", fields: [ "email" ], unique: true, inBackground: true }); | |||
// also supported for geo and fulltext indexes | |||
db.collection.ensureIndex({ type: "geo", fields: [ "latitude", "longitude"], inBackground: true }); | |||
db.collection.ensureIndex({ type: "geo", fields: [ "latitude", "longitude"], inBackground: true }); | |||
db.collection.ensureIndex({ type: "fulltext", fields: [ "text" ], minLength: 4, inBackground: true }) | |||
行为 | |||
仍在构建过程中的索引将无法通过ArangoDB API看到。但是,在仍然开始创建索引的同时,不可能通过sureIndex API 两次创建相同的索引。AQL查询也不会使用这些索引,直到索引报告已完全创建。请注意,在索引完全准备好之前,最初的sureIndex调用或HTTP请求仍将阻塞。因此,现有的单线程客户端程序可以安全地将inBackground选项设置为true并继续像以前一样工作。 | |||
如果要在后台建立索引,则不能重命名或删除集合。这些操作将阻塞,直到索引创建完成。前景索引也是如此。 | |||
在索引构建中断之后(即由于服务器崩溃),部分构建的索引将被删除。然后,在ArangoDB集群中,可能会在受影响的分片上自动重新创建索引。 | |||
性能 | |||
后台索引创建可能比“前景”索引创建慢,并且需要更多RAM。在繁重的写操作(特别是许多删除,更新或替换操作)下,后台索引创建需要在RAM中保留已删除文档的列表。如果此列表增加到数千万个条目,这可能变得难以为继。 | |||
建立索引始终(内部)是繁重的写操作,在负载较少的时候建立索引始终是一个好主意。 |
@ -1,240 +0,0 @@ | |||
经营者 | |||
AQL支持许多可在表达式中使用的运算符。有比较,逻辑,算术和三元运算符。 | |||
比较运算符 | |||
比较(或关系)运算符比较两个操作数。它们可以与任何输入数据类型一起使用,并将返回布尔结果值。 | |||
支持以下比较运算符: | |||
操作员 描述 | |||
== 平等 | |||
!= 不等式 | |||
< 少于 | |||
<= 小于或等于 | |||
> 比...更棒 | |||
>= 大于或等于 | |||
IN 测试值是否包含在数组中 | |||
NOT IN 测试值是否不包含在数组中 | |||
LIKE 测试字符串值是否与模式匹配 | |||
NOT LIKE 测试字符串值是否与模式不匹配 | |||
=~ 测试字符串值是否与正则表达式匹配 | |||
!~ 测试字符串值是否与正则表达式不匹配 | |||
如果可以评估比较结果,则每个比较运算符都将返回一个布尔值;如果比较结果为true,则返回true;否则返回false 。 | |||
比较运算符接受第一和第二操作数的任何数据类型。但是,IN并且NOT IN仅在其右侧操作数是数组的情况下才会返回有意义的结果。LIKE并且NOT LIKE仅在两个操作数均为字符串值时才执行。如果比较的操作数具有不同或不合理的类型,则比较运算符将不执行任何隐式类型转换。 | |||
AQL中比较操作的一些示例: | |||
0 == null // false | |||
1 > 0 // true | |||
true != null // true | |||
45 <= "yikes!" // true | |||
65 != "65" // true | |||
65 == 65 // true | |||
1.23 > 1.32 // false | |||
1.5 IN [ 2, 3, 1.5 ] // true | |||
"foo" IN null // false | |||
42 NOT IN [ 17, 40, 50 ] // true | |||
"abc" == "abc" // true | |||
"abc" == "ABC" // false | |||
"foo" LIKE "f%" // true | |||
"foo" NOT LIKE "f%" // false | |||
"foo" =~ "^f[o].$" // true | |||
"foo" !~ "[a-z]+bar$" // true | |||
该LIKE运营商检查是否其左操作数以其右操作数指定的模式相匹配。该模式可以包含常规字符和通配符。支持的通配符_将匹配单个任意字符,并%匹配任意数量的任意字符。文字%,_需要以反斜杠转义。反斜杠需要自己转义,这实际上意味着两个反斜线字符必须在文字百分号或下划线之前。在arangosh中,需要进行额外的转义,使其在要转义的字符之前总共加四个反斜杠。 | |||
"abc" LIKE "a%" // true | |||
"abc" LIKE "_bc" // true | |||
"a_b_foo" LIKE "a\\_b\\_foo" // true | |||
LIKE操作员执行的模式匹配区分大小写。 | |||
该NOT LIKE经营者具有相同特性的LIKE运营商,但与否定的结果。因此,它与相同NOT (… LIKE …)。请注意括号,这对于某些表达式是必需的: | |||
FOR doc IN coll | |||
RETURN NOT doc.attr LIKE "…" | |||
return表达式将转换为LIKE(!doc.attr, "…"),从而产生意外结果。NOT(doc.attr LIKE "…")变得更加合理! LIKE(doc.attr, "…")。 | |||
正则表达式运算符=~并!~期望它们的左手操作数是字符串,而期望它们的右手操作数是包含有效的正则表达式的字符串,如AQL函数REGEX_TEST()的文档中所指定 。 | |||
数组比较运算符 | |||
比较运算符也作为数组变量存在。在阵列变型中,操作者的前缀的关键字之一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支持以下逻辑运算符: | |||
&& 逻辑与运算符 | |||
|| 逻辑或运算符 | |||
! 逻辑非/否定运算符 | |||
AQL还支持逻辑运算符的以下替代形式: | |||
AND 逻辑与运算符 | |||
OR 逻辑或运算符 | |||
NOT 逻辑非/否定运算符 | |||
替代形式是别名,在功能上等同于常规运算符。 | |||
AQL中的两个操作数逻辑运算符将使用短路求值执行(除非其中一个操作数是子查询或包含子查询。在这种情况下,子查询将在逻辑运算符之前被提取一个求值)。 | |||
AQL中逻辑运算符的结果定义如下: | |||
lhs && rhslhs如果是false或将false转换为布尔值时将返回。如果将lhsis true或be true转换为布尔值, rhs则将返回。 | |||
lhs || rhslhs如果是true或将true转换为布尔值时将返回。如果将lhsis false或be false转换为布尔值, rhs则将返回。 | |||
! value将返回value转换为布尔值的取反值 | |||
AQL中逻辑操作的一些示例: | |||
u.age > 15 && u.address.city != "" | |||
true || false | |||
NOT u.isInvalid | |||
1 || ! 0 | |||
允许将非布尔值传递给逻辑运算符。任何非布尔操作数都将由运算符隐式转换为布尔值,而不会使查询中止。 | |||
在一个布尔值转换的工作原理如下: | |||
null 将被转换为 false | |||
布尔值保持不变 | |||
所有不等于零的数字为true,零为false | |||
空字符串是false,所有其他字符串是true | |||
数组([ ])和对象/文档({ })是true不论其内容如何 | |||
逻辑和与逻辑或运算的结果现在可以具有任何数据类型,并且不一定是布尔值。 | |||
例如,以下逻辑运算将返回布尔值: | |||
25 > 1 && 42 != 7 // true | |||
22 IN [ 23, 42 ] || 23 NOT IN [ 22, 7 ] // true | |||
25 != 25 // false | |||
…,而以下逻辑运算将不会返回布尔值: | |||
1 || 7 // 1 | |||
null || "foo" // "foo" | |||
null && true // null | |||
true && 23 // 23 | |||
算术运算符 | |||
算术运算符对两个数字操作数执行算术运算。算术运算的结果还是一个数值。 | |||
AQL支持以下算术运算符: | |||
+ 加成 | |||
- 减法 | |||
* 乘法 | |||
/ 师 | |||
% 模数 | |||
一元加号和一元减号也受支持: | |||
LET x = -5 | |||
LET y = 1 | |||
RETURN [-x, +y] | |||
// [5, 1] | |||
为了求幂,有一个数字函数 POW()。base ** exp不支持语法。 | |||
对于字符串连接,必须使用字符串函数 CONCAT()。将两个字符串与加号("foo" + "bar")结合使用将不起作用!另请参阅常见错误。 | |||
一些算术运算示例: | |||
1 + 1 | |||
33 - 99 | |||
12.4 * 4.5 | |||
13.0 / 0.1 | |||
23 % 7 | |||
-15 | |||
+9.99 | |||
算术运算符接受任何类型的操作数。将非数字值传递给算术运算符将使用TO_NUMBER()函数应用的类型转换规则将操作数转换为数字: | |||
null 将被转换为 0 | |||
false将转换为0,将true转换为1 | |||
有效数值保持不变,但NaN和Infinity将转换为 0 | |||
如果字符串值包含数字的有效字符串表示形式,则将它们转换为数字。字符串开头或结尾的所有空格都将被忽略。具有其他内容的字符串将转换为数字0 | |||
将一个空数组转换为0,将具有一个成员的数组转换为其唯一成员的数字表示形式。具有更多成员的数组将转换为number 0。 | |||
对象/文档将转换为数字0。 | |||
产生无效值的算术运算,例如1 / 0(除以零)也将产生结果值null。该查询不会终止,但是您可能会看到警告。 | |||
这里有一些例子: | |||
1 + "a" // 1 | |||
1 + "99" // 100 | |||
1 + null // 1 | |||
null + 1 // 1 | |||
3 + [ ] // 3 | |||
24 + [ 2 ] // 26 | |||
24 + [ 2, 4 ] // 0 | |||
25 - null // 25 | |||
17 - true // 16 | |||
23 * { } // 0 | |||
5 * [ 7 ] // 35 | |||
24 / "12" // 2 | |||
1 / 0 // 0 | |||
三元运算符 | |||
AQL还支持可用于条件评估的三元运算符。三元运算符期望布尔条件作为其第一个操作数,如果条件的计算结果为true,则返回第二个操作数的结果,否则返回第三个操作数。 | |||
例子 | |||
u.age > 15 || u.active == true ? u.userId : null | |||
还有只有两个操作数的三元运算符的快捷方式。当布尔条件的表达式和返回值应该相同时,可以使用此变体: | |||
例子 | |||
u.value ? : 'value is null, 0 or not present' | |||
范围运算符 | |||
AQL支持使用..运算符表达简单的数字范围。该运算符可用于轻松地迭代数字序列。 | |||
所述..操作者将产生整数值的阵列在所定义的范围内,与两个边界值包括在内。 | |||
例子 | |||
2010..2013 | |||
将产生以下结果: | |||
[ 2010, 2011, 2012, 2013 ] | |||
使用范围运算符等效于编写一个整数值的数组,该整数值在范围的边界所指定的范围内。如果范围运算符的边界为非整数,则它们将首先转换为整数值。 | |||
还有一个RANGE()函数。 | |||
数组运算符 | |||
AQL提供阵列运营商[*]为 数组变量扩展和 [**]用于阵列收缩。 | |||
运算符优先级 | |||
AQL中的运算符优先级与其他熟悉的语言相似(最低优先级优先): | |||
运营商 描述 | |||
, 逗号分隔符 | |||
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 (不是)在运算符中 | |||
<,<=,>=,> 小于,小于等于,大于等于,大于 | |||
.. 范围运算符 | |||
+, - 加,减 | |||
*,/,% 乘法,除法,模 | |||
!,+,- 逻辑否定,一元加,一元减 | |||
() 函数调用 | |||
. 会员访问 | |||
[] 索引值访问 | |||
[*] 扩张 | |||
:: 范围 | |||
括号(和)可用于强制执行不同的操作员评估顺序。 |