AQL基本语法
目录:
一、数据预览
本次使用的数据共有43条,每条数据包含姓氏、年龄、活动状态和特征等六个字段

其中每个特征都有一个随机字母作为文档密钥。特质标签有英文和德文。

地点由地名和经纬度组成:

二、基本的CRUD
创建集合:
在创建文档之前,需要创造一个放置它的集合,集合可以通过Web界面,arangosh或驱动程序来创建。AQL无法创建集合。

单击Web界面中的COLLECTIONS,然后单击Add Collection并键入 Charactersname。使用保存确认。新集合就出现在了列表中。
插入单个对象:
使用AQL插入文档

INSERT {
"name": "Ned",
"surname": "Stark",
"alive": true,
"age": 41,
"traits": ["A","H","C","N","P"]
} INTO Characters
语法:
INSERT document INTO collectionName
该文档是一个对象,由属性键和值对组成。属性键的引号在AQL中是可选的。键总是字符串,而属性值可以有不同的类型:
- null
- boolean (true, false)
- number (integer and floating point)
- string
- array
- object
批量插入对象:
AQL不允许INSERT在单个查询中针对同一集合的多个操作。但是可以使用FOR循环体,插入多个文档。
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 variableName = valueExpression
LET关键字定义了同名称的变量数据和对象值的数列,格式为[ {...}, {...}, ... ]
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
...
检索
检索集合中的所有文档:
FOR c IN Characters
RETURN c
语法:
FOR variableName IN collectionName
对于集合中的每个文档,依次分配给变量c,然后根据循环体返回该文档。
选取其中一个文档如下:
{
"_key": "2861650",
"_id": "Characters/2861650",
"_rev": "_V1bzsXa---",
"name": "Ned",
"surname": "Stark",
"alive": true,
"age": 41,
"traits": ["A","H","C","N","P"]
},
该文档包含我们存储的四个属性,以及数据库系统添加的另外三个属性:
_key:文档键,用户可以在创建文档时提供文档键,也可以自动分配唯一值,不能改变,只读
_id:集合名/文档键,只读
_rev:系统管理的修订版ID,只读
检索特定文档:
RETURN DOCUMENT("Characters", "2861650")
// --- or ---
RETURN DOCUMENT("Characters/2861650")
返回:
[
{
"_key": "2861650",
"_id": "Characters/2861650",
"_rev": "_V1bzsXa---",
"name": "Ned",
"surname": "Stark",
"alive": true,
"age": 41,
"traits": ["A","H","C","N","P"]
}
]
语法:
DOCUMENT()
使用_key或_id检索特定文档,该函数还允许一次获取多个文档
RETURN DOCUMENT("Characters", ["2861650", "2861653"])
// --- or ---
RETURN DOCUMENT(["Characters/2861650", "Characters/2861653"])
更新文档:
修改现有文件:
UPDATE "2861650" WITH { alive: false } IN Characters
语法:
UPDATE documentKey WITH object IN collectionName
用列出的属性更新指定的文档(如果它们不存在则添加它们),但保持其余不变。要替换整个文档内容,则要使用REPLACE函数:
REPLACE "2861650" WITH {
name: "Ned",
surname: "Stark",
alive: false,
age: 41,
traits: ["A","H","C","N","P"]
} IN Characters
该函数也适用于循环,例如为所有文档添加新属性:
FOR c IN Characters
UPDATE c WITH { season: 1 } IN Characters
删除文件:
语法:
REMOVE _key IN Collectiosname
要从集合中完全删除文档,需要执行REMOVE操作。它的工作方式与其他修改操作类似,但没有WITH子句:
REMOVE "2861650" IN Characters
三、匹配文件
语法:
FILTER
查找满足比_key相等更复杂的条件的文档,能够为要匹配的文档制定任意条件。
等于条件:
FOR c IN Characters
FILTER c.name == "Ned"
RETURN c
过滤条件如下:“ 字符文档的属性name必须等于字符串Ned ”。如果条件适用,则返回字符文档。
范围条件:
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 } //or FOR c IN Characters
FILTER c.age < 13 AND c.age != null
RETURN { name: c.name, age: c.age }
替代条件:
FOR c IN Characters
FILTER c.name == "Jon" OR c.name == "Joffrey"
RETURN { name: c.name, surname: c.surname }
四、排序和限制
限制语法:
LIMIT()
LIMIT后面跟着一个最大显示数的数字,限制结果显示行数。
FOR c IN Characters
LIMIT 5
RETURN c.name
还可以使用LIMIT来跳过一定数量的记录返回下一个n个文档:
FOR c IN Characters
LIMIT 2, 5
RETURN c.name
排序语法:
SORT()
DESC降序来反转排序顺序
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
}
此处FILTER的作用是仅保留surname为非空记录
五、组合
语法:
MERGE()
MERGE()的功能是将对象组合在一起。因为使用了原始字符属性{ traits: ... },所以后者被合并覆盖。
FOR c IN Characters
RETURN MERGE(c, { traits: DOCUMENT("Traits", c.traits)[*].en } )
六、图操作
创建图:
语法:
INSERT { _from: _id(A), _to: _id(B) } INTO ChildOf
实例:
首先,创建一个新的集合,并确保将集合类型更改为Edge。

然后,通过查询多个集合的数据,将结果存入边集合中
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( //FIRST()提取第一个元素
FOR c IN Characters
FILTER c.name == rel.parent.name //筛选条件
FILTER c.surname == rel.parent.surname
LIMIT 1
RETURN c._id //返回_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 //剔除_id都为空的记录
INSERT { _from: childId, _to: parentId } INTO ChildOf //将数据插入边集合
RETURN NEW //返回数据
也可以直接创建边数据:
INSERT { _from: "Characters/robb", _to: "Characters/ned" } INTO ChildOf
遍历图:
语法:
FOR v IN 1..1 OUTBOUND _id ChildOf
RETURN v.name
其中1..1为遍历深度
实例:
FOR c IN Characters
FILTER c.name == "Bran"
FOR v IN 1..1 OUTBOUND c ChildOf
RETURN v.name
返回
[
"Ned",
"Catelyn"
]
遍历的情况如下图:

若是反向遍历,则需要使用到INBOUND关键字:
FOR c IN Characters
FILTER c.name == "Tywin"
FOR v IN 2..2 INBOUND c ChildOf
RETURN DISTINCT v.name
输出:
[
"Joffrey"
]
遍历情况如下:

需要注意的是,“1..1”限制了遍历深度为1,“2..2”限制了遍历深度为2,而"1..2"限制遍历深度既可以为1也可以为2。
七、地理空间查询
地点数据
创建地点集合:

录入地点数据:
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
设置地理空间索引:
在COLLECTIONS界面,添加新的Indexes,设置为coordinate字段:


查找附近的位置
语法:
NEAR()
找到最接近的坐标参考点
FOR loc IN NEAR(Locations, 53.35, -6.26, )
RETURN {
name: loc.name,
latitude: loc.coordinate[],
longitude: loc.coordinate[]
}
输出:
[
{
"name": "Vaes Dothrak",
"latitude": 54.16776,
"longitude": -6.096125
},
{
"name": "Winterfell",
"latitude": 54.368321,
"longitude": -5.581312
},
{
"name": "Dragonstone",
"latitude": 55.167801,
"longitude": -6.815096
}
]
查找半径内的位置
语法:
WITHIN()
从参考点搜索给定半径内的位置
FOR loc IN WITHIN(Locations, 53.35, -6.26, * )
RETURN {
name: loc.name,
latitude: loc.coordinate[],
longitude: loc.coordinate[]
}
输出
[
{
"name": "Vaes Dothrak",
"latitude": 54.16776,
"longitude": -6.096125
},
{
"name": "Winterfell",
"latitude": 54.368321,
"longitude": -5.581312
}
]
按距离查找位置:
语法:
NEAR()或WITHIN()
通过添加一个可选的第五个参数返回到参考点的距离。必须是一个字符串:
FOR loc IN NEAR(Locations, 53.35, -6.26, , "distance")
RETURN {
name: loc.name,
latitude: loc.coordinate[],
longitude: loc.coordinate[],
distance: loc.distance /
}
输出:
[
{
"name": "Vaes Dothrak",
"latitude": 54.16776,
"longitude": -6.096125,
"distance": 91.56658640314431
},
{
"name": "Winterfell",
"latitude": 54.368321,
"longitude": -5.581312,
"distance": 121.66399816395028
},
{
"name": "Dragonstone",
"latitude": 55.167801,
"longitude": -6.815096,
"distance": 205.31879386198324
}
]
使用AQL遇到的问题:
问题1:如何对查询结果进行计数并返回?
解决方法:
RETURN COUNT(FOR v IN visitors FILTER v.ip == "127.0.0.1" RETURN )
参考资料:
https://docs.arangodb.com/3.3/AQL/Tutorial/
AQL基本语法的更多相关文章
- AQL Subset Compiler:手把手教你如何写一个完整的编译器
项目地址:https://github.com/laiy/Awesome-Complier. 转载请注明出处. 前言 这是学校里编译原理课程的大作业,此Project十分适合编译原理的学习,让基本不听 ...
- Qradar SIEM--查询利器 AQL
对于 SIEM 平台来说,好用的查询方式非常重要.之前有体验基于 ELK 搭建的平台,在 kibana 上面是可以通过一些 filter 来做一些过滤并且是支持 lucene 的语法,包括一些简单的逻 ...
- 我的MYSQL学习心得(一) 简单语法
我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- Swift与C#的基础语法比较
背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性
回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...
- Velocity初探小结--velocity使用语法详解
做java开发的朋友一般对JSP是比较熟悉的,大部分人第一次学习开发View层都是使用JSP来进行页面渲染的,我们都知道JSP是可以嵌入java代码的,在远古时代,java程序员甚至在一个jsp页面上 ...
- node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法
1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...
- C#语法糖大汇总
首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...
随机推荐
- QT两个窗口相互切换
信号(signals)与槽(slots)是QT重要机制,例子使用了C++11 lambda表达式进行了信号与槽的连接. 实现两个窗口通过点击按钮完成互相切换,注意子窗口只能发送信号,不能处理,所有信号 ...
- tomcat设定shared lib共享同样的jar
在项目越来越多的时候,部署在tomcat的发布包也会越来越多,这样难免有很多相同的jar会被加载,占用大量的永久存续区内存,通过设定shared lib来控制相同的jar只加载一个,这样有以下好处: ...
- 【SQL server基础】object_id()函数
在SQLServer数据库中,如果查询数据库中是否存在指定名称的索引或者外键约束等,经常会用到object_id('name','type')方法,做笔记如下: ? 语法:object_id('obj ...
- eShopOnContainers学习系列(二):数据库连接健康检查
项目里使用数据库的时候,我们有时候需要知道数据库当前的健康状态,特别是当数据库连接不上的时候能够立马获悉.eShopOnContainers里存在着大量的服务健康.连接健康的检查,数据库连接是其中之一 ...
- 谷歌助力,快速实现 Java 应用容器化
原文地址:梁桂钊的博客 博客地址:http://blog.720ui.com 欢迎关注公众号:「服务端思维」.一群同频者,一起成长,一起精进,打破认知的局限性. Google 在 2018 年下旬开源 ...
- hover和position共用出现的问题
hover 鼠标移入的样式 position 定位属性 包含 relative 相对定位 absolute 绝对定位为 fixed 固定定位 hover作用范围 可以实现自己样式的 ...
- 【柠檬班】史上最简单的Jmeter跨线程组取参数值的两种办法(不写代码)【原创】
如果你工作中已经在用jmeter做接口测试,或性能测试了,你可能会遇到一个麻烦,哪就是jmeter的变量值不能跨线程组传递. 看,官方就已经给出了解释.这个不是jmeter的缺陷,这是jmeter ...
- ELK 学习笔记之 elasticsearch 版本控制
版本控制: elasticsearch 版本控制: 内部版本控制 外部版本控制 内部版本控制: 内部版本会检查你提供的版本值和文档的版本值是否一致,如果不一致就报错,一致则可以更新. curl -XP ...
- php实现商城秒杀
这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...
- 关于人工智能和python
人工智能的话题在近几年可谓是相当火热,前几天看快本时其中有一个环节就是关于人工智能的,智能家电.智能机器人.智能工具等等,在我的印象里,提到人工智能就会出现 Python,然后我便在网上查找了相关信息 ...