开源NoSQL数据库:ArangoDB入门指南

数据库 其他数据库
本文这个新手指南会让你熟悉 ArangoDB。我们将介绍安装并运行一个本地 ArangoDB 服务器、使用Web界面与之交互、将示例数据存储在数据库中等等。

[[209070]]

概述

这个新手指南会让你熟悉 ArangoDB。我们将介绍,

  • 安装并运行一个本地 ArangoDB 服务器
  • 使用Web界面与之交互
  • 将示例数据存储在数据库中
  • 查询数据库以再次检索数据
  • 编辑和删除现有数据

安装

去 arangodb.com/download,选择您的操作系统并下载 ArangoDB。如果有包管理器,你也可以参考说明如何通过包管理器进行安装。

在 Linux 下如果您安装了二进制包,服务器会自动启动。

在 MacOS X 下,如果你用包管理器 homebrew 安装 ArangoDB,通过命令启动服务,/usr/local/sbin/arangod.

在 Windows 下把 ArangoDB 安装为服务,它会自动启动。未安装为服务的情况下,需要运行位于安装目录中的 bin 目录下的 arangod.exe。你可能必须以管理员身份运行,以获得对 C:\Program Files 目录的写权限。

关于安装 ArangoDB 更深入的信息,以及可用的启动参数,在集群中安装等,参阅安装文档。

保护安装

默认安装包含 _system 数据库和 root 用户。

基于 Debian 的软件包和 Winsows Installer 都会在安装过程中询问密码。基于 RedHat 的软件包则会设置一个随机密码。对于其它安装包,你需要执行

shell> arango-secure-installation

这会要求输入一个 root 密码并保存起来。

Web 界面

服务本身(arangod)是基于 HTTP/REST 的,但是你可以使用图形化的 Web 界面让操作变得简单。还有 arangosh,一个异步 shell,用来与服务器进行交互。如果你是开发者,你可能更喜欢使用 shell 而不是 GUI。目前它还没有提供像语法高亮这样的功能。

在项目中开始使用 ArangoDB 的时候,你会寻找官方或社区使用与项目相同语言编写的驱动。驱动实现了可以在项目编程语言中轻松使用的编程接口,与服务器进行完全地交互。因此,除非你想自己写驱动或者直接使用原始接口,否则理所当然地,应该忽略 HTTP API。

为了熟悉数据库系统你可以将驱动放置一边而使用 web 界面 (代码名 Aardvark) 进行基本交互. web 界面将会在你启动 arangod 之后变为可用. 你可以在浏览器中通过 http://localhost:8529 进行访问 – 如果不可以,请查看 故障排除.

默认情况下, 验证已启用. 默认用户为 root. 依据所用的安装方法,安装过程会提示输入 root 密码或者默认 root 密码为空 (参看 以上).

 

接下来你会被询问使用哪个数据库。所有的服务器实例带有一个 _system 数据库. 选择该数据库并继续.

 

然后你会看到如下的服务器统计面板:

 

要了解关于接口的更详细描述,参看 Web Interface.

数据库,集合与文档

数据库是集合的集合. 集合存储记录, 记录被称为文档. 集合等价于 RDBMS 中的表, 而文档可以被认为是表中的行. 区别在于你不需要预先定义有哪些列 (或者属性). 任意集合中的所有文档可以拥有任意的属性键与值. 然而实际上一个集合中的文档具有相似的结构, 但是数据库系统本身并不会关心,无论你的数据是什么样子,数据库系统都会在其上执行稳定而快速的操作.

现在你可以停留在默认的 _system 数据库中并使用 web 接口来创建集合与文档. 点击 COLLECTIONS 菜单项, 然后选择 Add Collection 菜单. 为其指定一个名字,例如 users, 保持其他的设置不变 (我们希望它是一个文档集合) 并保存. 会出现一个标记为 users 的新菜单项, 你可以点击打开.

目录还没有任何文档. 点击右侧带有白色加号的绿色圆环来创建该集合中的***个文档. 对话框会询问你 _key. 你可以将该区域留空并点击 Create 来让数据据系统赋值一个自动生成 (唯一) 的键. 注意 _key 属性是不可修改的, 这意味着一旦文档被创建你不可以修改该键. 你可以用作文档键的内容在命名约定 中有相应的描述.

在这种情况下,自动生成的键值也许是 “9883” (_key 总是字符串!), 而文档 _id 也许是 “users/9883” . 除了一些系统属性,在文档中并没有其他内容. 让我们通过点击 (空对象) 左侧的图标添加一个自定义属性, 然后 添加. 两个文本输入框会变得可用, FIELD (属性键) 与 VALUE (属性值). 输入名字作为键,输入你的名字作为值. 添加 另一个属性,将其命名为年龄,并将其设置为你的年龄. 点击保存来保存这些修改. 如果你点击 ArangoDB 图标右侧顶点的集合: users , 文档浏览器将会显示 users 集合中的文档,而你可以在列表中看到你刚刚创建的文档.

查询数据库

是时候通过AQL(ArangoDB’ query language)ArangoDB查询语言来取得我们的文档了。我们可以直接通过我们创建的_id属性查找文档(当然我们还可以使用其它选项)。点击QUERIES菜单栏来显示query editor(查询编辑器)输入以下的内容(具体取决于你的document ID):

  1. RETURN DOCUMENT("users/9883"

然后点击Execute来启动查询,结果如下所示:

  1.   { 
  2.     "_key""9883"
  3.     "_id""users/9883"
  4.     "_rev""9883"
  5.     "age": 32, 
  6.     "name""John Smith" 
  7.   } 
  8.  

结果出现在编辑器下方。如你所见,程序返回了整个文档,包含着系统属性。DOCUMENT() 函数会根据你提供的_keys或者_ids返回一系列或者单个文档。我们管返回的结果叫做查询结果,它是一个数组,包含了我们的文档查询结果(我们可能会得到不只一个文档,但是即使只有一个文档结果,它仍然会返回最上层的数组)。

这种类型的查询称为数据访问查询。这种查询不会创建、更改或删除数据。还有另一种类型的查询,称为数据修改查询。让我们使用修改查询插入第二个文档:

  1. INSERT { name"Katie Foster", age: 27 } INTO users 

查询非常容易看懂: INSERT 关键词告诉ArangoDB我们想插入一些东西。后面紧跟着的是我们要插入的东西,在这个案例中是一个拥有两个属性的文档。 花括号{ } 表示文件,或者说是对象。我们所说的文件是指集合中的记录。当用JSON编码时,我们叫它对象。对象也可以嵌套。下面举个例子:

  1.   "name": { 
  2.     "first""Katie"
  3.     "last""Foster" 
  4.   } 
  5.  

INTO 必须跟在每一个 INSERT 操作后面,后面再接上我们储存文档的集合的名字。注意集合的名字不必加上引号。

如果你运行上面的查询语句,会返回一个空数组,因为你没有用 RETURN 关键词指定要返回的内容。 RETURN 关键词在修改查询中是可选项,但在数据访问查询中是必选项。就算用上 RESULT,返回值也可能是空数组,比如制定文档无法找到的情况。尽管结果为空,以上的查询仍然会创建新用户文件。你可以在文档浏览器中验证这一点。

这一次我们新建一个用户,并且让新的结果返回。

  1. INSERT { name"James Hendrix", age: 69 } INTO users 
  2.  
  3. RETURN NEW  

NEW 是一个虚拟变量,指的是用INSERT语句新建的文档。查询结果如下:

  1.   { 
  2.     "_key""10074"
  3.     "_id""users/10074"
  4.     "_rev""10074"
  5.     "age": 69, 
  6.     "name""James Hendrix" 
  7.   } 
  8.  

现在我们一个有三个用户了。如何用一条语句返回全部数据呢?下面的方法不起作用:

  1. RETURN DOCUMENT("users/9883"
  2.  
  3. RETURN DOCUMENT("users/9915"
  4.  
  5. RETURN DOCUMENT("users/10074" 

这里仅有一条 RETURN 语句,如果你尝试执行,则会抛出系统错误. DOCUMENT() 函数提供了一个补充签名来指定多文档处理,所以我们可以:

  1. RETURN DOCUMENT( ["users/9883""users/9915""users/10074"] ) 

所有3个文档的带有 _ids 的数组会被传递给函数. 数组通过方括号 [ ] 表示,而其元素使用逗号进行分隔.

但是如果我们添加更多用户会怎样呢? 我们同时需要修改查询来获取新添加的用户. 关于我们的查询,我们希望表达的是: “对于 users 集合中的每一个用户, 返回用户文档”. 我们可以使用 FOR 循环格式化该查询:

  1. FOR user IN users 
  2.  
  3. RETURN user  

它表达的是对 users 中的所有文档进行迭代并使用user 作为变量名, 从而我们可以用来指代当前用户文档. 它可以被称为 doc, u 或 ahuacatlguacamole, 这取决于你. 然而建议使用一个简短并自描述的名字.

循环体告诉系统返回变量 user 的值, 这是一个用户文档. 可以像下面这样返回所有用户文档:

  1.   { 
  2.     "_key""9915"
  3.     "_id""users/9915"
  4.     "_rev""9915"
  5.     "age": 27, 
  6.     "name""Katie Foster" 
  7.   }, 
  8.   { 
  9.     "_key""9883"
  10.     "_id""users/9883"
  11.     "_rev""9883"
  12.     "age": 32, 
  13.     "name""John Smith" 
  14.   }, 
  15.   { 
  16.     "_key""10074"
  17.     "_id""users/10074"
  18.     "_rev""10074"
  19.     "age": 69, 
  20.     "name""James Hendrix" 
  21.   } 
  22.  

也许你已经注意到返回的文档顺序与插入顺序并不相同. ArangoDB 并不保证文档顺序,除非你显式对其进行排序. 我们可以很容易添加了一个 SORT 操作:

  1. FOR user IN users 
  2.  
  3. SORT user._key 
  4.  
  5. RETURN user  

这依然不会返回预期的结果: James (10074) 会在 John (9883) 与 Katie (9915) 之前返回. 原因在于 _key 属性在 ArangoDB 中是一个字符串,而不是一个数字. 字符串的单个字符会被进行比较. 1 小于 9 ,因而结果是 “正确”的. 如果我们希望使用数值作为 _key 属性的值,我们可以将字符串转换为数字并用其进行排序. 然而这样做有一些影响T. 我们***排序其他内容. 年龄怎么样?以降序排列吗?

  1. FOR user IN users 
  2.  
  3. SORT user.age DESC 
  4.  
  5. RETURN user  

用户的数据会以如下的顺序返回: James (69), John (32), Katie (27)。与用DESC返回降序结果不同, ASC返回升序结果。 ASC是默认的选项,可以省略。

我们可能需要根据用户的年龄返回一个子集。让我们返回30岁以上的用户的数据:

  1. FOR user IN users 
  2.  
  3. FILTER user.age > 30 
  4.  
  5. SORT user.age 
  6.  
  7. RETURN user  

这么做会按顺序返回John and James。 Katie’s age的属性不满足三十岁以上的条件,她只有27岁,因此不再结果之中。我们可以修改她的年龄,使她重新包含在返回结果之中,使用如下的查询语句:

  1. UPDATE "9915" WITH { age: 40 } IN users 
  2.  
  3. RETURN NEW  

UPDATE 允许部分编辑已存在的文档. 另外有 REPLACE, 会移除所有属性 (除了 _key 与 _id 保持不变) 并且仅添加部分属性. 另一方面 UPDATE 替换指定的属性而保持其他属性不变.

UPDATE 关键字后跟文档键 (或者带有 _key 属性的文档 / 对象) 来指定要修改的文档. 要更新的属性作为对象使用 WITH关键字写入. IN 表示在哪个集合中执行该操作, 类似 INTO (这里两个关键字可以互换). 如果我们使用 NEW 伪变量则会返回应用修改的全部文档:

  1.   { 
  2.     "_key""9915"
  3.     "_id""users/9915"
  4.     "_rev""12864"
  5.     "age": 40, 
  6.     "name""Katie Foster" 
  7.   }  

相反如果我们使用 REPLACE , name 属性会丢失. 使用 UPDATE, 属性会被保留 (如果我们有其他的属性,也同样适用该规则).

让我们再次运行 FILTER 查询, 但是这一次仅返回用户名:

  1. FOR user IN users 
  2.  
  3. FILTER user.age > 30 
  4.  
  5. SORT user.age 
  6.  
  7. RETURN user.name  

这会返回所有3个用户的名字:

  1.  
  2. "John Smith"
  3.  
  4. "Katie Foster"
  5.  
  6. "James Hendrix" 
  7.  
  8.  

如果仅返回一个属性的子集,则将其称为投影. 另一种投影类型是改变结果的结构:

  1. FOR user IN users 
  2.  
  3. RETURN { userName: user.name, age: user.age }  

该查询为所有的用户文档定义了输出格式. 用户名作为 userName 返回,而不是 name, 在该示例中 age 与属性性键相同:

  1.   { 
  2.     "userName""James Hendrix"
  3.     "age": 69 
  4.   }, 
  5.   { 
  6.     "userName""John Smith"
  7.     "age": 32 
  8.   }, 
  9.   { 
  10.     "userName""Katie Foster"
  11.     "age": 40 
  12.   } 

也可以计算新值:

  1. FOR user IN users 
  2.  
  3. RETURN CONCAT(user.name"'s age is "user.age)  

CONCAT() 是一个将元素合并为字符串的函数. 在这里我们用其为所有用户返回一个描述. 正如你看到的,结果集合并不总是一个对象数组:

  1.  
  2. "James Hendrix's age is 69"
  3.  
  4. "John Smith's age is 32"
  5.  
  6. "Katie Foster's age is 40" 
  7.  
  8.  

现在让我们来做一些疯狂的事情: 对于用户集合中的所有文档,再次对所有用户文档进行迭代并返回用户组合,例如 John 与 Katie. 对于该问题,我们可以在一个循环内部使用一个循环来获得叉积 (所有用户记录的所有可能组合, 3 3 = 9). 然而我们并不希望得到类似 John + John* 的组合, 所以让我们使用一个过滤器条件来去除类似的组合:

  1. FOR user1 IN users 
  2.  
  3. FOR user2 IN users 
  4.  
  5. FILTER user1 != user2 
  6.  
  7. RETURN [user1.name, user2.name 

我们得到6对组合。类似 James + John 与 John + James 的组合是重复的,但是已足够好:

  1.   [ "James Hendrix""John Smith" ], 
  2.   [ "James Hendrix""Katie Foster" ], 
  3.   [ "John Smith""James Hendrix" ], 
  4.   [ "John Smith""Katie Foster" ], 
  5.   [ "Katie Foster""James Hendrix" ], 
  6.   [ "Katie Foster""John Smith" ] 
  7.  

我们可以像下面这样计算两个年龄之和并计算一些新的内容:

  1. FOR user1 IN users 
  2.   FOR user2 IN users 
  3.     FILTER user1 != user2 
  4.     RETURN { 
  5.         pair: [user1.name, user2.name], 
  6.         sumOfAges: user1.age + user2.age 
  7.     }  

我们引入一个新的属性 sumOfAges 并将两个年龄相加作为其值:

  1.   { 
  2.     "pair": [ "James Hendrix""John Smith" ], 
  3.     "sumOfAges": 101 
  4.   }, 
  5.   { 
  6.     "pair": [ "James Hendrix""Katie Foster" ], 
  7.     "sumOfAges": 109 
  8.   }, 
  9.   { 
  10.     "pair": [ "John Smith""James Hendrix" ], 
  11.     "sumOfAges": 101 
  12.   }, 
  13.   { 
  14.     "pair": [ "John Smith""Katie Foster" ], 
  15.     "sumOfAges": 72 
  16.   }, 
  17.   { 
  18.     "pair": [ "Katie Foster""James Hendrix" ], 
  19.     "sumOfAges": 109 
  20.   }, 
  21.   { 
  22.     "pair": [ "Katie Foster""John Smith" ], 
  23.     "sumOfAges": 72 
  24.   } 
  25.  

如果我们希望过滤新属性来仅返回总和小于100的组合,我们应该定义一个变量来临时存储总和,从而我们可以在 FILTER 语句以及 RETURN 语句中使用:

  1. FOR user1 IN users 
  2.   FOR user2 IN users 
  3.     FILTER user1 != user2 
  4.     LET sumOfAges = user1.age + user2.age 
  5.     FILTER sumOfAges < 100 
  6.     RETURN { 
  7.         pair: [user1.name, user2.name], 
  8.         sumOfAges: sumOfAges 
  9.     }  

LET 关键字后跟指定的变量名 (sumOfAges), 然后是 = 符号与值或表达式来定义变量的值. 在这里我们重用我们的表达式来计算总和. 然后我们使用另一个 FILTER 来略过不需要的组合并使用我们之前声明的变量. 我们使用用户名与所计算的年龄值的数组返回一个投影,为些我们再次使用变量:

  1.   { 
  2.     "pair": [ "John Smith""Katie Foster" ], 
  3.     "sumOfAges": 72 
  4.   }, 
  5.   { 
  6.     "pair": [ "Katie Foster""John Smith" ], 
  7.     "sumOfAges": 72 
  8.   } 
  9.  

小贴士: 当定义对象时, 如果所要求的属性键与属性值所用的变量相同i, 你可以使用简写形式: { sumOfAges } 替代 { sumOfAges: sumOfAges }.

***,让我们删除一个用户文档:

  1. REMOVE "9883" IN users 

它会删除用户 John (_key: “9883”). 我们也可以在循环中移除文档 (同样适用于 INSERT, UPDATE 与 REPLACE):

  1. FOR user IN users 
  2.     FILTER user.age >= 30 
  3.     REMOVE user IN users  

该查询会删除年龄大于等于 30 的所有用户.

如何继续

在AQL 中可探索更多内容以及 ArangoDB 提供的更多功能. 继续阅读其他章节并使用测试数据库试验以促进你的知识.

如果你希望立即编写更多的 AQL 查询,请查看:

  • 数据查询: 数据访问与修改查询
  • 高级操作: FOR, FILTER 的详细描述以及该简介中未涉及的更多操作
  • 函数: 所提供函数的参数

ArangoDB程序

ArangoDB包有以下程序:

  • arangod: ArangoDB数据库守护进程. 此服务器程序旨在作为守护程序进程运行,并通过TCP / HTTP向各种客户端连接到服务器。
  • arangosh: ArangoDB shell. 客户端实现read-eval-print-Loop(REPL)并提供函数来访问和管理ArangoDB服务器。
  • arangoimp: ArangoDB服务器的 批量导入器 。它支持JSON和CSV。
  • arangodump:以JSON格式创建ArangoDB数据库备份 的工具。
  • arangorestore: 将备份数据加载回ArangoDB数据库的工具。
  • arango-dfdb: ArangoDB的数据文件调试器。它主要用于开发ArangoDB。
  • arangobench: A基准测试工具。 它可以用于性能和服务器功能测试。 
责任编辑:庞桂玉 来源: 36大数据
相关推荐

2011-07-19 09:08:50

JavaNoSQL

2024-02-02 10:51:53

2023-07-28 08:27:03

MongoDB数据库

2019-03-20 14:44:53

数据库MySQLExcel

2021-09-28 09:25:05

NoSQL数据库列式数据库

2011-10-09 09:38:03

OracleNoSQL

2019-03-20 15:59:11

NoSQLRedis数据库

2019-07-08 10:36:34

数据库WebNoSQL

2010-04-01 09:45:38

NoSQL

2024-03-28 09:00:00

NoSQL数据库

2023-12-19 09:36:35

PostgreSQL数据库开源

2011-05-16 10:29:44

HandlerSockNoSQL

2011-03-25 14:40:29

Trinity数据库

2019-07-23 11:41:45

数据库SQLDocker

2011-04-14 11:14:21

OracleNoSQLMySQL

2011-07-13 09:58:15

HBase

2014-02-27 10:08:33

NoSQL

2010-08-13 16:40:27

CouchDBAndroid SDKAndroid

2017-05-25 10:11:46

数据库令牌节点

2020-10-31 22:01:40

NoSQL数据库
点赞
收藏

51CTO技术栈公众号