在本章中,我们将讨论如何使用AQL查询数据.我们在前面的章节中已经讨论过ArangoDB已经开发了自己的查询语言,它的名称是AQL.
现在让我们开始与AQL交互.如下图所示,在Web界面中,按位于导航栏顶部的 AQL编辑器选项卡.将出现一个空白查询编辑器.
如果需要,可以通过单击右上角的"查询"或"结果"选项卡,从结果视图切换到编辑器,反之亦然.如下图所示 :
除此之外,编辑器还具有语法突出显示,撤消/重做功能和查询保存功能.有关详细参考,可以查看官方文档.我们将重点介绍AQL查询编辑器的一些基本和常用功能.
在AQL中,查询表示最终结果为实现,但不是实现最终结果的过程.此功能通常称为语言的声明属性.此外,AQL也可以查询和修改数据,因此可以通过组合这两个过程来创建复杂的查询.
请注意,AQL完全符合ACID标准.阅读或修改查询将全部结束或根本不结束.即使阅读文档的数据也会以一致的数据单位结束.
我们在已经创建的歌曲集合中添加了两首新的歌曲.您可以复制以下查询,而不是键入,将其粘贴到AQL编辑器中并减去;
FOR song IN [ { title: "Air-Minded Executive", lyricist: "Johnny Mercer", composer: "Bernie Hanighen", Year: 1940, _key: "Air-Minded" }, { title: "All Mucked Up", lyricist: "Johnny Mercer", composer: "Andre Previn", Year: 1974, _key: "All_Mucked" } ] INSERT song IN songs
按左下方的执行按钮.
它将在歌曲集合中写入两个新文档.
此查询描述了FOR循环在AQL中的工作方式;它遍历JSON编码文档列表,对集合中的每个文档执行编码操作.不同的操作可以是创建新结构,过滤,选择文档,修改或将文档插入数据库(参见瞬时示例).从本质上讲,AQL可以有效地执行CRUD操作.
要查找我们数据库中的所有歌曲,让我们再次运行以下查询,相当于 SELECT * FROM songs 一个SQL类型的数据库(因为编辑器记忆了最后一个查询,按 * New * 按钮来清理编辑器) :
FOR song IN songs RETURN song
结果集将显示到目前为止保存的歌曲列表在歌曲集合中,如下面的屏幕截图所示.
可以将 FILTER,SORT 和 LIMIT 等操作添加到 For循环主体中以缩小和排序结果.
FOR song IN songs FILTER song.Year > 1940 RETURN song
上述查询将在1940年的结果选项卡中创建歌曲(见下图).
在此示例中使用了文档密钥,但是任何其他属性也可以用作过滤的等价物.由于文档密钥保证是唯一的,因此只有一个文档与此筛选器匹配.对于其他属性,情况可能并非如此.要返回活动用户的子集(由名为status的属性确定),按名称按升序排序,我们使用以下语法 :
FOR song IN songs FILTER song.Year > 1940 SORT song.composer RETURN song LIMIT 2
我们故意包含这个例子.在这里,我们观察到AQL以红色突出显示的查询语法错误消息.此语法突出显示错误,有助于调试查询,如下面的屏幕截图所示.
现在让我们运行正确的查询(注意更正) :
FOR song IN songs FILTER song.Year > 1940 SORT song.composer LIMIT 2 RETURN song
AQL配备所有支持的数据类型的多个函数.查询中的变量赋值允许构建非常复杂的嵌套构造.这样,数据密集型操作更接近后端数据而不是客户端(例如浏览器).要理解这一点,我们首先将任意持续时间(长度)添加到歌曲中.
让我们从第一个函数开始,即更新函数 :
UPDATE { _key: "All_Mucked" } WITH { length: 180 } IN songs
我们可以看到一个文档已经写好,如上面的截图所示.
现在让我们更新其他文档(歌曲).
UPDATE { _key: "Affable_Balding" } WITH { length: 200 } IN songs
我们可以现在检查我们所有的歌曲都有一个新属性长度 :
FOR song IN songs RETURN song
[ { "_key": "Air-Minded", "_id": "songs/Air-Minded", "_rev": "_VkC5lbS---", "title": "Air-Minded Executive", "lyricist": "Johnny Mercer", "composer": "Bernie Hanighen", "Year": 1940, "length": 210 }, { "_key": "Affable_Balding", "_id": "songs/Affable_Balding", "_rev": "_VkC4eM2---", "title": "Affable Balding Me", "lyricist": "Johnny Mercer", "composer": "Robert Emmett Dolan", "Year": 1950, "length": 200 }, { "_key": "All_Mucked", "_id": "songs/All_Mucked", "_rev": "_Vjah9Pu---", "title": "All Mucked Up", "lyricist": "Johnny Mercer", "composer": "Andre Previn", "Year": 1974, "length": 180 }, { "_key": "Accentchuate_The", "_id": "songs/Accentchuate_The", "_rev": "_VkC3WzW---", "title": "Accentchuate The Politics", "lyricist": "Johnny Mercer", "composer": "Harold Arlen", "Year": 1944, "length": 190 } ]
为了说明使用其他AQL关键字,如LET,FILTER,SORT,等等,我们现在以 mm:ss 格式格式化歌曲的持续时间.
FOR song IN songs FILTER song.length > 150 LET seconds = song.length % 60 LET minutes = FLOOR(song.length / 60) SORT song.composer RETURN { Title: song.title, Composer: song.composer, Duration: CONCAT_SEPARATOR(':',minutes, seconds) }
这一次我们将返回歌曲标题和持续时间. 返回功能允许您为每个输入文档创建一个新的JSON对象.
现在我们将讨论AQL数据库的"连接"功能.
让我们首先创建一个集合 composer_dob .此外,我们将通过在查询框中运行以下查询来创建具有假定出生日期的四个文档 :
FOR dob IN [ {composer: "Bernie Hanighen", Year: 1909} , {composer: "Robert Emmett Dolan", Year: 1922} , {composer: "Andre Previn", Year: 1943} , {composer: "Harold Arlen", Year: 1910} ] INSERT dob in composer_dob
为突出与SQL的相似性,我们在AQL中呈现嵌套的FOR循环查询,导致REPLACE操作,首先在内循环中迭代,在所有作曲家的dob上迭代,然后在所有相关歌曲上创建,创建包含属性 song_with_composer_key 的新文档,而不是歌曲属性.
此处查询 :
FOR s IN songs FOR c IN composer_dob FILTER s.composer == c.composer LET song_with_composer_key = MERGE( UNSET(s, 'composer'), {composer_key:c._key} ) REPLACE s with song_with_composer_key IN songs
现在让我们运行查询 FOR song IN songs RETURN song 再次查看歌曲收藏的变化情况.
[ { "_key": "Air-Minded", "_id": "songs/Air-Minded", "_rev": "_Vk8kFoK---", "Year": 1940, "composer_key": "5501", "length": 210, "lyricist": "Johnny Mercer", "title": "Air-Minded Executive" }, { "_key": "Affable_Balding", "_id": "songs/Affable_Balding", "_rev": "_Vk8kFoK--_", "Year": 1950, "composer_key": "5505", "length": 200, "lyricist": "Johnny Mercer", "title": "Affable Balding Me" }, { "_key": "All_Mucked", "_id": "songs/All_Mucked", "_rev": "_Vk8kFoK--A", "Year": 1974, "composer_key": "5507", "length": 180, "lyricist": "Johnny Mercer", "title": "All Mucked Up" }, { "_key": "Accentchuate_The", "_id": "songs/Accentchuate_The", "_rev": "_Vk8kFoK--B", "Year": 1944, "composer_key": "5509", "length": 190, "lyricist": "Johnny Mercer", "title": "Accentchuate The Politics" } ]
上述查询完成了数据迁移过程,为每首歌曲添加了 composer_key .
现在下一个查询又是一个嵌套的FOR循环que ry,但是这次导致了Join操作,将相关作曲家的名字(在"composer_key"的帮助下选中)添加到每首歌曲 :
FOR s IN songs FOR c IN composer_dob FILTER c._key == s.composer_key RETURN MERGE(s, { composer: c.composer } )
[ { "Year": 1940, "_id": "songs/Air-Minded", "_key": "Air-Minded", "_rev": "_Vk8kFoK---", "composer_key": "5501", "length": 210, "lyricist": "Johnny Mercer", "title": "Air-Minded Executive", "composer": "Bernie Hanighen" }, { "Year": 1950, "_id": "songs/Affable_Balding", "_key": "Affable_Balding", "_rev": "_Vk8kFoK--_", "composer_key": "5505", "length": 200, "lyricist": "Johnny Mercer", "title": "Affable Balding Me", "composer": "Robert Emmett Dolan" }, { "Year": 1974, "_id": "songs/All_Mucked", "_key": "All_Mucked", "_rev": "_Vk8kFoK--A", "composer_key": "5507", "length": 180, "lyricist": "Johnny Mercer", "title": "All Mucked Up", "composer": "Andre Previn" }, { "Year": 1944, "_id": "songs/Accentchuate_The", "_key": "Accentchuate_The", "_rev": "_Vk8kFoK--B", "composer_key": "5509", "length": 190, "lyricist": "Johnny Mercer", "title": "Accentchuate The Politics", "composer": "Harold Arlen" } ]