- ArangoDB 教程
- ArangoDB - 首頁
- 一個多模型優先資料庫
- ArangoDB – 優勢
- 基本概念和術語
- ArangoDB – 系統要求
- ArangoDB – 命令列
- ArangoDB - Web 介面
- ArangoDB - 示例案例場景
- 資料模型和建模
- ArangoDB - 資料庫方法
- ArangoDB - CRUD 操作
- 使用 Web 介面進行 CRUD 操作
- 使用 AQL 查詢資料
- ArangoDB - AQL 示例查詢
- ArangoDB – 如何部署
- ArangoDB 有用資源
- ArangoDB - 快速指南
- ArangoDB - 有用資源
- ArangoDB - 討論
使用 AQL 查詢資料
在本章中,我們將討論如何使用 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
按下左下角的“執行”按鈕。
它將在**songs**集合中寫入兩個新文件。
此查詢描述了 FOR 迴圈在 AQL 中的工作方式;它迭代 JSON 編碼文件列表,對集合中每個文件執行編碼操作。不同的操作可以是建立新結構、過濾、選擇文件、修改或將文件插入資料庫(參考即時示例)。從本質上講,AQL 可以有效地執行 CRUD 操作。
要查詢資料庫中的所有歌曲,讓我們再次執行以下查詢,相當於 SQL 型別資料庫中的**SELECT * FROM songs**(因為編輯器會記住最後一個查詢,請按**“新建”**按鈕清除編輯器)。
FOR song IN songs RETURN song
結果集將顯示到目前為止儲存在**songs**集合中的歌曲列表,如下面的螢幕截圖所示。
可以將**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 中的複雜查詢
AQL 配備了所有支援資料型別的多個函式。查詢內的變數賦值允許構建非常複雜的巢狀結構。這樣,資料密集型操作會更靠近後端的資料,而不是靠近客戶端(例如瀏覽器)。為了理解這一點,讓我們首先將任意時長(長度)新增到歌曲中。
讓我們從第一個函式開始,即 Update 函式。
UPDATE { _key: "All_Mucked" }
WITH { length: 180 }
IN songs
我們可以看到已寫入了一個文件,如上圖所示。
現在讓我們更新其他文件(歌曲)。
UPDATE { _key: "Affable_Balding" }
WITH { length: 200 }
IN songs
現在我們可以檢查我們的所有歌曲是否都有一個新的屬性**length**。
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)
}
這次我們將返回歌曲標題和時長。**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 操作,首先在內部迴圈中迭代所有作曲家的出生日期,然後迭代所有關聯的歌曲,建立一個包含屬性**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
現在讓我們再次執行查詢**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 迴圈查詢,但這次導致聯接操作,將關聯的作曲家姓名(使用`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"
}
]