当前位置: 首页 > 科技观察

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

时间:2023-03-15 13:05:32 科技观察

概述本初学者指南将让您熟悉ArangoDB。我们将介绍、安装和运行本地ArangoDB服务器,使用Web界面与其交互在数据库中存储样本数据查询数据库再次检索数据编辑和删除现有数据以安装转到arangodb.com/download,选择您的操作系统并下载ArangoDB。如果有包管理器,也可以参考如何通过包管理器安装的说明。在Linux下,如果你安装二进制包,服务器会自动启动。在MacOSX下,如果使用包管理器homebrew安装ArangoDB,请通过命令/usr/local/sbin/arangod启动服务。在Windows下将ArangoDB安装为服务,它会自动启动。如果没有作为服务安装,需要运行位于安装目录bin目录下的arangod.exe。您可能必须以管理员身份运行才能获得对C:\ProgramFiles目录的写入权限。有关安装ArangoDB的更多深入信息,以及可用的启动参数、在集群中安装等,请参阅安装文档。安全安装默认安装包含_system数据库和root用户。基于Debian的软件包和Winsows安装程序都会在安装过程中要求输入密码。基于RedHat的软件包设置了一个随机密码。对于其他安装,您需要执行shell>arango-secure-installation这将要求输入root密码并保存。Web界面服务本身(arangod)基于HTTP/REST,但您可以使用图形化Web界面来简化操作。还有arangosh,一个用于与服务器交互的异步shell。如果您是一名开发人员,您可能更喜欢使用shell而不是GUI。目前它不提供语法高亮等功能。当开始在项目中使用ArangoDB时,你会寻找与项目使用相同语言编写的官方或社区驱动程序。驱动程序实现了一个编程接口,可以很容易地在项目的编程语言中使用它来与服务器完全交互。因此,除非你想自己编写驱动程序或直接使用原始接口,否则你当然应该忽略HTTPAPI。要熟悉数据库系统,您可以将驱动程序放在一边,使用Web界面(代号Aardvark)进行基本交互。启动arangod后,Web界面将可用。您可以在浏览器中通过http://localhost:8529访问它-如果没有,请参阅故障排除。默认情况下,身份验证已启用。默认用户是root。根据使用的安装方法,安装过程将提示输入root密码或默认root密码为空(见上文)。接下来,您将被询问要使用哪个数据库。所有服务器实例都带有一个_system数据库。选择该数据库并继续。然后您将看到服务器统计面板,如下所示:有关界面的更详细说明,请参阅Web界面。数据库、集合和文档数据库都是集合Collections。集合存储记录,记录称为文档。集合相当于RDBMS中的表,文档可以看作是表中的行。不同之处在于您不需要预先定义有哪些列(或属性)。在任何集合中集合中的所有文档都可以具有任意属性键和值。但是,实际上一个集合中的文档有着相似的结构,只是数据库系统本身并不关心,无论你的数据是什么样子,数据库系统都会对其进行稳定和快速的操作。现在您可以留在默认的_system数据库中,并使用Web界面创建集合和文档。单击COLLECTIONS菜单项,然后选择AddCollection菜单。给它起个名字,比如users,其他设置保持不变(我们希望它是一个文档的集合)并保存。将有一个标记为用户的新菜单项,您可以单击该菜单项将其打开。该目录还没有任何文件。单击右侧带有白色加号的绿色环以创建集合中的第一个文档。该对话框将要求您输入_key。您可以将此字段留空并单击创建让数据库系统分配一个自动生成的(唯一的)键。请注意,_key属性是不可变的,这意味着一旦创建了文档,您就无法修改密钥。命名约定中描述了可以用作文档密钥的内容。在这种情况下,自动生成的键值可能是"9883"(_key总是一个字符串!),文档_id可能是"users/9883"。除了一些系统属性外,文档中没有其他内容。让我们通过单击(emptyobject)左侧的图标来添加自定义属性,然后添加。两个文本输入框将变为可用,FIELD(属性键)和VALUE(属性值)。输入您的姓名作为键,输入您的姓名作为值。添加另一个属性,将其命名为Age,并将其设置为您的年龄。单击保存以保存这些更改。如果你点击ArangoDB图标右上角的集合:users,DocumentationBrowser会显示users集合中的文档,你可以在列表中看到你刚刚创建的Document。查询数据库是时候通过AQL了(阿兰goDB'查询语言)ArangoDB查询语言获取我们的文档我们可以直接通过我们创建的_id属性来查找文档(当然我们也可以使用其他选项)。点击QUERIES菜单栏显示查询编辑器(queryeditor),输入以下内容(根据你的文档ID):RETURNDOCUMENT("users/9883")点击Execute开始查询,结果如下:[{"_key":"9883","_id":"users/9883","_rev":"9883","age":32,"name":"JohnSmith"}]结果显示在编辑器下方。如您所见,该程序返回整个文档,包括系统属性。DOCUMENT()函数根据您提供的_keys或_ids返回一个列表或单个文档。我们返回的结果称为查询结果,它是一个包含我们文档查询结果的数组(我们可能会得到多个文档,但即使只有一个文档结果,它仍然会返回顶级数组)。这种类型的查询称为数据访问查询。此类查询不会创建、更改或删除数据。还有另一种类型的查询称为数据修改查询。让我们使用修改查询插入第二个文档:INSERT{name:"KatieFoster",age:27}INTousers查询非常容易理解:INSERT关键字告诉ArangoDB我们想要插入一些东西。紧随其后的是我们要插入的内容,在本例中是一个具有两个属性的文档。大括号{}表示文件或对象。我们所说的文件是指集合中的记录。当以JSON编码时,我们称它为对象。对象也可以嵌套。下面是一个示例:{"name":{"first":"Katie","last":"Foster"}}INTO必须跟在每个INSERT操作之后,然后是我们存储文档的集合的名称。请注意,集合的名称不需要用引号引起来。如果您运行上面的查询,它将返回一个空数组,因为您没有使用RETURN关键字指定要返回的内容。RETURN关键字在修改查询中是可选的,但在数据访问查询中是必需的。即使使用RESULT,返回值也可能是一个空数组,比如找不到指定的文档时。即使结果为空,上述查询仍会创建一个新的用户文件。您可以在文档浏览器中验证这一点。这次我们创建一个新用户并返回新结果。INSERT{name:"JamesHendrix",age:69}INTOusersRETURNNEWNEW是一个虚拟变量,它引用带有INSERT语句的新创建的文档。查询结果如下:[{"_key":"10074","_id":"users/10074","_rev":"10074","age":69,"name":"JamesHendrix"}]现在我们有一个有三个用户。如何用一条语句返回所有数据?下面的方法不起作用:RETURNDOCUMENT("users/9883")RETURNDOCUMENT("users/9915")RETURNDOCUMENT("users/10074")这里只有一个RETURN语句,如果你尝试执行的话,会出现系统错误抛出。DOCUMENT()函数提供了一个补充签名来指定多文档处理,因此我们可以:RETURNDOCUMENT(["users/9883","users/9915","users/10074"])包含所有3个文档的_ids将传递给函数。该数组用方括号[]表示,其元素用逗号分隔。但是如果我们添加更多用户呢?我们还需要修改查询以获取新添加的用户。关于我们的查询,我们想表达的是:“对于用户集合中的每个用户,返回用户文档”。我们可以使用FOR循环来格式化查询:FORuserINusersRETURNuser在users中表示用户遍历所有文档,并使用user作为变量名,这样我们就可以引用当前用户文档。它可以称为doc、u或ahuacatlguacamole,由您决定。但是,建议使用简短且自我描述的名称。循环体告诉系统返回变量user的值,即用户文档。您可以像这样返回所有用户文档:[{"_key":"9915","_id":"users/9915","_rev":"9915","age":27,"name":"KatieFoster"},{"_key":"9883","_id":"users/9883","_rev":"9883","age":32,"name":"JohnSmith"},{"_key":"10074","_id":"users/10074","_rev":"10074","age":69,"name":"JamesHendrix"}]也许你已经注意到返回的文档与插入时的顺序不一样。ArangoDB不保证文档顺序,除非你明确地对它们进行排序。我们可以轻松地添加一个SORT操作:FORuserINusersSORTuser._keyRETURNuser仍然没有返回预期结果:James(10074)将在John(9883)和Katie(9915)之前返回。原因是ArangoDB中的_key属性是字符串,不是数字。比较字符串的各个字符。1小于9,所以结果是“正确的”。如果我们想使用数字作为_key属性的值,我们可以将字符串转换为数字并使用它们进行排序。但是,这样做会产生一些影响。我们***排序其他内容。年龄呢?降序排列?FORuserINusersSORTuser.ageDESCRETURNuser用户数据将按以下顺序返回:James(69),John(32),Katie(27)不是用DESC降序返回结果,ASC返回升序排序结果。ASC是默认选项,可以省略。我们可能需要根据用户的年龄返回一个子集。让我们返回30岁以上用户的数据:FORuserINusersFILTERuser.age>30SORTuser.ageRETURNuser这将按顺序返回John和James。凯蒂的年龄属性不符合30岁以上的条件。她只有27岁,所以她已经不在结果中了。我们可以修改她的年龄,以便她再次包含在返回的结果中,使用以下查询语句:UPDATE"9915"WITH{age:40}INusersRETURNNEWUPDATE允许对现有文档进行部分编辑。还有REPLACE,会去掉所有的Attributes(除了_key和_id不变),只增加部分属性。另一方面,UPDATE替换指定的属性并保持其他属性不变。UPDATE关键字后跟文档键(或具有_key属性的文档/对象)以指定要修改的文档。要更新的属性使用WITH关键字作为对象写入。IN表示在哪个集合中执行操作,类似于INTO(这里两个关键字可以互换)。如果我们使用NEW伪变量,应用程序修改的所有文档将被返回:[{"_key":"9915","_id":"users/9915","_rev":"12864","age":40,"name":"KatieFoster"}相反,如果我们使用REPLACE,name属性将丢失。使用UPDATE,属性被保留(如果我们有其他属性,同样的规则适用)。让我们再次运行FILTER查询,但这次只返回用户名:FORuserINusersFILTERuser.age>30SORTuser.ageRETURNuser.name这将返回所有3个用户的名称:["JohnSmith","KatieFoster","JamesHendrix"]如果只有一个子集属性被返回,它被称为投影。另一个投影类型是改变结果的结构:FORuserINusersRETURN{userName:user.name,age:user.age}这个查询定义了所有用户文档的输出格式。用户名返回为userName,而不是name,在此示例中年龄与属性键相同:[{"userName":"JamesHendrix","age":69},{"userName":"JohnSmith","age":32},{"userName":"KatieFoster","age":40}]也可以计算新值:FORuserINusersRETURNCONCAT(user.name,"'sageis",user.age)CONCAT()是一个将元素组合成字符串的函数,这里我们用它来返回对所有用户的描述。可以看到,得到的集合并不总是一个数组ofobjects:["JamesHendrix'sageis69","JohnSmith'sageis32","KatieFoster'sageis40"]现在让我们做一些疯狂的事情:对于用户集合中的所有文档,再次遍历所有用户文档并返回用户组合,例如John和Katie。对于这个问题,我们可以使用一个循环中的循环来获得叉积(所有用户记录的所有可能组合,33=9)。但是,我们不想得到像John+John*这样的组合,所以让我们使用过滤条件来删除相似的组合:FORuser1INusersFORuser2INusersFILTERuser1!=user2RETURN[user1.name,user2.name]我们得到6个组合像James+John和John+James这样的组合是重复的,但已经足够好了:[["JamesHendrix","JohnSmith"],["JamesHendrix","KatieFoster"],["JohnSmith","JamesHendrix"],["JohnSmith","KatieFoster"],["KatieFoster","JamesHendrix"],["KatieFoster","JohnSmith"]]我们可以像这样对两个年龄求和并计算一些新的东西:FORuser1INusersFORuser2INusersFILTERuser1!=user2RETURN{pair:[user1.name,user2.name],sumOfAges:user1.age+user2.age}我们引入一个新属性sumOfAges并将两个年龄添加为它的值:[{"pair":["JamesHendrix","JohnSmith"],"sumOfAges":101},{"pair":["JamesHendrix","KatieFoster"],"sumOfAges":109},{"pair":["JohnSmith","JamesHendrix"],"sumOfAges":101},{"pair":["JohnSmith","KatieFoster"],"sumOfAges":72},{"pair":["KatieFoster","JamesHendrix"t;],"sumOfAges":109},{"pair":["KatieFoster","JohnSmith"],"sumOfAges":72}]如果我们想过滤新属性只返回总和小于的组合100,我们应该定义一个变量来临时存储总和,以便我们可以在FILTER语句和RETURN语句中使用它:,user2.name],sumOfAges:sumOfAges}LET关键字后跟指定的变量名(sumOfAges),后跟=号和值或表达式来定义变量的值。在这里,我们重用我们的表达式来计算总和。然后我们使用另一个FILTER来跳过所需的组合并使用我们之前声明的变量。我们返回一个包含用户名数组和计算出的年龄值的投影,为此我们再次使用变量:[{"pair":["JohnSmith","KatieFoster"],"sumOfAges":72},{"pair":["KatieFoster","JohnSmith"],"sumOfAges":72}]提示:在定义对象时,如果需要的属性键和属性值使用变量同i,可以使用简写:{sumOfAges}代替{sumOfAges:sumOfAges}.***,让我们删除一个用户文档:REMOVE"9883"INusers它将删除用户John(_key:“9883”)。我们还可以循环删除文档(也适用于INSERT、UPDATE和REPLACE):FORuserINusersFILTERuser.age>=30REMOVEuserINusers该查询删除所有年龄大于等于30的用户。如何继续探索AQL中的更多内容以及ArangoDB必须提供的更多功能。继续阅读其他章节并尝试使用测试数据库来提高您的知识。如果想马上写更多的AQL查询,请参考:数据查询:数据访问和修改查询高级操作:FOR、FILTER等本介绍未涉及的操作函数详解:ArangoDB程序提供函数的参数ArangoDB包有以下程序:arangod:ArangoDB数据库守护进程。该服务器程序旨在作为守护进程运行,并通过TCP/HTTP连接到服务器到各种客户端arangosh:ArangoDBshell。客户端实现read-eval-print-Loop(REPL)并提供访问和管理ArangoDB服务器的功能。arangoimp:ArangoDB服务器的批量导入器。它支持JSON和CSV。arangodump:一种以JSON格式创建ArangoDB数据库备份的工具。arangorestore:将备份数据加载回ArangoDB数据库的工具。arango-dfdb:ArangoDB的数据文件调试器。主要用于开发ArangoDB。arangobench:基准测试工具。它可用于性能和服务器功能测试。