📜  使用AQL查询数据

📅  最后修改于: 2020-11-28 13:13:30             🧑  作者: Mango


在本章中,我们将讨论如何使用AQL查询数据。在前面的章节中,我们已经讨论过ArangoDB已经开发了自己的查询语言,并且以AQL命名。

现在让我们开始与AQL进行交互。如下图所示,在Web界面中,按导航栏顶部的AQL编辑器选项卡。一个空白的查询编辑器将出现。

如有需要,您可以通过单击右上角的“查询”或“结果”选项卡,从结果视图切换到编辑器,反之亦然,如下图所示:

从结果视图切换到编辑器

除其他外,编辑器还具有语法突出显示,撤消/重做功能和查询保存功能。有关详细参考,请参阅官方文档。我们将重点介绍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操作。

要查找数据库中的所有歌曲,让我们再次运行以下查询,等效于SQL类型数据库的SELECT * FROM歌曲(因为编辑器会记住上一个查询,因此请按* New *按钮以清理编辑器)-

FOR song IN songs
RETURN song

结果集将显示到目前为止保存在歌曲集中的歌曲列表,如下面的屏幕快照所示。

歌曲清单

可以将诸如FILTER,SORTLIMIT之类的操作添加到For循环主体中,以缩小和排序结果。

FOR song IN songs
FILTER song.Year > 1940
RETURN song

上面的查询将在“结果”选项卡中显示1940年后创建的歌曲(请参见下图)。

查询Year_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中的复杂查询

AQL为所有受支持的数据类型配备了多种功能。查询中的变量赋值允许构建非常复杂的嵌套构造。这样,数据密集型操作就更靠近后端的数据,而不是移动到客户端(例如浏览器)。为了理解这一点,让我们首先将任意持续时间(长度)添加到歌曲中。

让我们从第一个函数开始,即Update函数-

UPDATE { _key: "All_Mucked" }
WITH { length: 180 }
IN songs

AQL中的复杂查询

我们可以看到上面的屏幕截图显示了一个文档的编写。

现在让我们也更新其他文档(歌曲)。

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) 
}

AQL 2中的复杂查询

这次我们将返回歌曲名称以及持续时间。 Return函数使您可以创建一个新的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而不是song属性。

查询在这里-

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

Song Wth作曲家调

现在,让我们再次运行查询FOR歌曲IN歌曲RETURN歌曲,以查看歌曲集合的变化。

输出

[
   {
      "_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循环查询,但这一次导致了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"
   }
]

向每首歌曲添加作曲家琴键