上一篇: 饮冰十年-人工智能-ArangoDB-01-初识ArangoDB
一、SQL 和 AQL
如果您使用过 MySQL、MariaDB 或 PostgreSQL 等关系数据库管理系统 (RDBMS),那么您熟悉它们的查询语言,即 SQL(结构化查询语言)。
ArangoDB 的查询语言称为 AQL(ArangoDB’ query language)。它的用途类似于 SQL。
两者都支持读取和修改数据库系统中的记录。但是,AQL 不支持数据定义操作,例如创建和删除数据库、集合和索引。
尽管数据库系统的数据模型不同,但两种语言之间还是有一些相似之处。它们是声明性语言。查询表示您想要的结果,而不是您希望如何获得结果。它们的目标是人类可读,使用英语中的关键字和读起来像句子的语法。它们还尝试独立于客户端,这意味着无论客户端使用何种编程语言或环境,所有客户端的语言和语法都是相同的。
最显着的区别可能是 AQL 中循环的概念,这使得它感觉更像是一种编程语言。AQL 一开始比普通 SQL 复杂一点,但从长远来看,它提供了更大的灵活性。它更自然地适合无架构模型,并使查询语言非常强大,同时保持易于读取和编写。
例如,SQL 的子句和 AQL 的操作是等效的,因为它们都定义了返回结果的条件。但 SQL 对查询子句使用固定顺序,确定子句在语句中必须出现的位置。在 AQL 中,操作可以以不同的顺序进行,甚至可以多次发生,从而为您提供很大的自由度。
AQL 支持复杂的查询模式,包括子查询、联接、聚合、地理空间查询、全文搜索和排名,以及图形遍历,其中一些在标准 SQL 中是有限的,甚至是不可能的。
尽管存在任何差异,但任何具有 SQL 背景的人在学习 AQL 时都应该没有困难。
二、基本查询
1、INSERT
它使用以下语法:
INSERT document INTO collection
1.1 插入单行/文档
SQL格式:
INSERT INTO users (name, gender) VALUES ("John Doe", "m");
AQL:
INSERT { name: "John Doe", gender: "m" } INTO users
1.2 插入多行/文档
SQL格式:
INSERT INTO users (name, gender) VALUES ("John Doe", "m"),("Jane Smith", "f");
AQL:
FOR user IN [{ name: "John Doe", gender: "m" },{ name: "Jane Smith", gender: "f" }] INSERT user INTO users
1.3 从表/集合中插入行/文档
SQL格式:
INSERT INTO backup (uid, name, gender) SELECT uid, name, gender FROM users WHERE active = 1;
AQL:
FOR user IN users FILTER user.active == 1 INSERT user INTO backup
1.4 生成测试行/文档
SQL格式:
使用脚本或存储过程,或者从现有表进行填充。
AQL:
FOR i IN 1..1000 INSERT { name: CONCAT("test", i), gender: (i % 2 == 0 ? "f" : "m") } INTO users
2、UPDATE 查询
AQL 中的 UPDATE
关键字可部分修改集合中的文档。此操作有两种语法可用:
UPDATE document IN collection
UPDATE keyExpression WITH document IN collection
2.1 更新单行/文档
SQL格式:
UPDATE users SET name = "John Smith" WHERE id = 1;
AQL:
UPDATE { _key: "1" } WITH { name: "John Smith" } IN users
2.2 添加具有默认值的新列/属性
SQL格式:
ALTER TABLE users ADD COLUMN numberOfLogins INTEGER NOT NULL default 0;
AQL:
FOR user IN users UPDATE user WITH { numberOfLogins: 0 } IN users
2.3 添加具有计算值的新列/属性
SQL格式:
ALTER TABLE users ADD COLUMN numberOfLogins INTEGER NOT NULL default 0; UPDATE users
SET numberOfLogins = (SELECT COUNT(*) FROM logins WHERE user = users.id) WHERE active = 1;
AQL:
FOR user IN users FILTER user.active == 1 UPDATE user WITH { numberOfLogins: LENGTH( FOR login IN logins FILTER login.user == user._key COLLECT WITH COUNT INTO numLogins RETURN numLogins ) } IN users
2.4 添加可选列/属性
SQL格式:不可直接实现,必须将不符合条件的行的列设置为默认值(例如 NULL)。
ALTER TABLE users ADD COLUMN isImportantUser INTEGER default NULL, ADD COLUMN dateBecameImportant INTEGER default NULL; UPDATE users SET isImportantUser = 1, dateBecameImportant = UNIX_TIMESTAMP() WHERE isImportantUser IS NULL
AND ( SELECT COUNT(*) FROM logins WHERE user = user.id ) > 50;
AQL:
LET date = DATE_NOW() FOR user IN users FILTER user.isImportantUser == null LET numberOfLogins = ( FOR login IN logins FILTER login.user == user._key COLLECT WITH COUNT INTO numLogins RETURN numLogins ) FILTER numberOfLogins > 50 UPDATE user WITH { isImportantUser: 1, dateBecameImportant: date } IN users
2.5 删除列/属性
SQL格式:
ALTER TABLE users DROP COLUMN numberOfLogins;
AQL:
FOR user IN users UPDATE user WITH { numberOfLogins: null } IN users OPTIONS { keepNull: false }
2.6 仅删除某些行/文档的列/属性
SQL格式:
不可直接,必须将符合条件的行的列设置为默认值(例如 NULL)。
UPDATE users SET isImportantUser = NULL, dateBecameImportant = NULL WHERE isImportantUser = 1 AND active = 0;
AQL:
FOR user IN users FILTER user.isImportantUser == 1 AND user.active == 0 UPDATE user WITH { isImportantUser: null, dateBecameImportant: null } IN users OPTIONS { keepNull: false }
3、REPLACE 查询
REPLACE
关键字可完全修改集合中的文档。此操作有两种语法可用:
REPLACE document IN collection
REPLACE keyExpression WITH document IN collection
3.1 替换单行/文档
SQL格式:
REPLACE INTO users (name, gender) VALUES ("Jane Smith", "f") WHERE id = 1;
AQL:
REPLACE { _key: "1" } WITH {name: "Jane Smith", gender: "f" } IN users
3.2 替换表/集合中的多个行/文档
SQL格式:
REPLACE INTO users (name, gender) SELECT name, gender FROM backup;
AQL:
FOR user IN backup
REPLACE user
WITH {name: backup.name, gender: backup.gender}
IN users