AQL基本語法


目錄:

一、數據預覽

本次使用的數據共有43條,每條數據包含姓氏、年齡、活動狀態和特征等六個字段

其中每個特征都有一個隨機字母作為文檔密鑰。特質標簽有英文和德文。

地點由地名和經緯度組成:

 

二、基本的CRUD

創建集合:

在創建文檔之前,需要創造一個放置它的集合,集合可以通過Web界面,arangosh或驅動程序來創建。AQL無法創建集合。

單擊Web界面中的COLLECTIONS,然后單擊Add Collection並鍵入 Charactersname。使用保存確認。新集合就出現在了列表中。

插入單個對象:

使用AQL插入文檔

INSERT { "name": "Ned", "surname": "Stark", "alive": true, "age": 41, "traits": ["A","H","C","N","P"] } INTO Characters

語法:

INSERT document INTO collectionName

該文檔是一個對象,由屬性鍵和值對組成。屬性鍵的引號在AQL中是可選的。鍵總是字符串,而屬性值可以有不同的類型:

  • null
  • boolean (true, false)
  • number (integer and floating point)
  • string
  • array
  • object 

批量插入對象:

AQL不允許INSERT在單個查詢中針對同一集合的多個操作。但是可以使用FOR循環體,插入多個文檔。

LET data = [ { "name": "Robert", "surname": "Baratheon", "alive": false, "traits": ["A","H","C"] }, { "name": "Jaime", "surname": "Lannister", "alive": true, "age": 36, "traits": ["A","F","B"] }, { "name": "Catelyn", "surname": "Stark", "alive": false, "age": 40, "traits": ["D","H","C"] }, { "name": "Cersei", "surname": "Lannister", "alive": true, "age": 36, "traits": ["H","E","F"] }, { "name": "Daenerys", "surname": "Targaryen", "alive": true, "age": 16, "traits": ["D","H","C"] }, { "name": "Jorah", "surname": "Mormont", "alive": false, "traits": ["A","B","C","F"] }, { "name": "Petyr", "surname": "Baelish", "alive": false, "traits": ["E","G","F"] }, { "name": "Viserys", "surname": "Targaryen", "alive": false, "traits": ["O","L","N"] }, { "name": "Jon", "surname": "Snow", "alive": true, "age": 16, "traits": ["A","B","C","F"] }, { "name": "Sansa", "surname": "Stark", "alive": true, "age": 13, "traits": ["D","I","J"] }, { "name": "Arya", "surname": "Stark", "alive": true, "age": 11, "traits": ["C","K","L"] }, { "name": "Robb", "surname": "Stark", "alive": false, "traits": ["A","B","C","K"] }, { "name": "Theon", "surname": "Greyjoy", "alive": true, "age": 16, "traits": ["E","R","K"] }, { "name": "Bran", "surname": "Stark", "alive": true, "age": 10, "traits": ["L","J"] }, { "name": "Joffrey", "surname": "Baratheon", "alive": false, "age": 19, "traits": ["I","L","O"] }, { "name": "Sandor", "surname": "Clegane", "alive": true, "traits": ["A","P","K","F"] }, { "name": "Tyrion", "surname": "Lannister", "alive": true, "age": 32, "traits": ["F","K","M","N"] }, { "name": "Khal", "surname": "Drogo", "alive": false, "traits": ["A","C","O","P"] }, { "name": "Tywin", "surname": "Lannister", "alive": false, "traits": ["O","M","H","F"] }, { "name": "Davos", "surname": "Seaworth", "alive": true, "age": 49, "traits": ["C","K","P","F"] }, { "name": "Samwell", "surname": "Tarly", "alive": true, "age": 17, "traits": ["C","L","I"] }, { "name": "Stannis", "surname": "Baratheon", "alive": false, "traits": ["H","O","P","M"] }, { "name": "Melisandre", "alive": true, "traits": ["G","E","H"] }, { "name": "Margaery", "surname": "Tyrell", "alive": false, "traits": ["M","D","B"] }, { "name": "Jeor", "surname": "Mormont", "alive": false, "traits": ["C","H","M","P"] }, { "name": "Bronn", "alive": true, "traits": ["K","E","C"] }, { "name": "Varys", "alive": true, "traits": ["M","F","N","E"] }, { "name": "Shae", "alive": false, "traits": ["M","D","G"] }, { "name": "Talisa", "surname": "Maegyr", "alive": false, "traits": ["D","C","B"] }, { "name": "Gendry", "alive": false, "traits": ["K","C","A"] }, { "name": "Ygritte", "alive": false, "traits": ["A","P","K"] }, { "name": "Tormund", "surname": "Giantsbane", "alive": true, "traits": ["C","P","A","I"] }, { "name": "Gilly", "alive": true, "traits": ["L","J"] }, { "name": "Brienne", "surname": "Tarth", "alive": true, "age": 32, "traits": ["P","C","A","K"] }, { "name": "Ramsay", "surname": "Bolton", "alive": true, "traits": ["E","O","G","A"] }, { "name": "Ellaria", "surname": "Sand", "alive": true, "traits": ["P","O","A","E"] }, { "name": "Daario", "surname": "Naharis", "alive": true, "traits": ["K","P","A"] }, { "name": "Missandei", "alive": true, "traits": ["D","L","C","M"] }, { "name": "Tommen", "surname": "Baratheon", "alive": true, "traits": ["I","L","B"] }, { "name": "Jaqen", "surname": "H'ghar", "alive": true, "traits": ["H","F","K"] }, { "name": "Roose", "surname": "Bolton", "alive": true, "traits": ["H","E","F","A"] }, { "name": "The High Sparrow", "alive": true, "traits": ["H","M","F","O"] } ] FOR d IN data INSERT d INTO Characters

語法:

LET variableName = valueExpression

LET關鍵字定義了同名稱的變量數據和對象值的數列,格式為[ {...}, {...}, ... ]

FOR variableName IN expression

用於迭代數據數組的每個元素 。在每個循環中,將一個元素分配給變量d。然后在INSERT語句中使用此變量。相當於下面的格式:

INSERT { "name": "Robert", "surname": "Baratheon", "alive": false, "traits": ["A","H","C"] } INTO Characters INSERT { "name": "Jaime", "surname": "Lannister", "alive": true, "age": 36, "traits": ["A","F","B"] } INTO Characters ...

檢索

檢索集合中的所有文檔:

FOR c IN Characters
    RETURN c

語法:

FOR variableName IN collectionName

對於集合中的每個文檔,依次分配給變量c,然后根據循環體返回該文檔。

選取其中一個文檔如下:

 { "_key": "2861650", "_id": "Characters/2861650", "_rev": "_V1bzsXa---", "name": "Ned", "surname": "Stark", "alive": true, "age": 41, "traits": ["A","H","C","N","P"] },

該文檔包含我們存儲的四個屬性,以及數據庫系統添加的另外三個屬性:

_key:文檔鍵,用戶可以在創建文檔時提供文檔鍵,也可以自動分配唯一值,不能改變,只讀

_id:集合名/文檔鍵,只讀

_rev:系統管理的修訂版ID,只讀

檢索特定文檔:

RETURN DOCUMENT("Characters", "2861650") // --- or ---
RETURN DOCUMENT("Characters/2861650")

返回:

[ { "_key": "2861650", "_id": "Characters/2861650", "_rev": "_V1bzsXa---", "name": "Ned", "surname": "Stark", "alive": true, "age": 41, "traits": ["A","H","C","N","P"] } ] 

語法:

DOCUMENT()

使用_key或_id檢索特定文檔,該函數還允許一次獲取多個文檔

RETURN DOCUMENT("Characters", ["2861650", "2861653"]) // --- or ---
RETURN DOCUMENT(["Characters/2861650", "Characters/2861653"])

更新文檔:

修改現有文件:

UPDATE "2861650" WITH { alive: false } IN Characters

語法:

UPDATE documentKey WITH object IN collectionName

用列出的屬性更新指定的文檔(如果它們不存在則添加它們),但保持其余不變。要替換整個文檔內容,則要使用REPLACE函數:

REPLACE "2861650" WITH { name: "Ned", surname: "Stark", alive: false, age: 41, traits: ["A","H","C","N","P"] } IN Characters 

該函數也適用於循環,例如為所有文檔添加新屬性:

FOR c IN Characters UPDATE c WITH { season: 1 } IN Characters

刪除文件:

語法:

REMOVE _key IN Collectiosname

要從集合中完全刪除文檔,需要執行REMOVE操作。它的工作方式與其他修改操作類似,但沒有WITH子句:

REMOVE "2861650" IN Characters 

三、匹配文件

語法:

FILTER

查找滿足比_key相等更復雜的條件的文檔,能夠為要匹配的文檔制定任意條件。

等於條件:

FOR c IN Characters FILTER c.name == "Ned" RETURN c

過濾條件如下:“ 字符文檔的屬性name必須等於字符串Ned ”。如果條件適用,則返回字符文檔。

范圍條件:

FOR c IN Characters FILTER c.age >= 13 RETURN c.name

多種條件:

FOR c IN Characters FILTER c.age < 13 FILTER c.age != null RETURN { name: c.name, age: c.age } //or
 FOR c IN Characters FILTER c.age < 13 AND c.age != null RETURN { name: c.name, age: c.age } 

替代條件:

FOR c IN Characters FILTER c.name == "Jon" OR c.name == "Joffrey" RETURN { name: c.name, surname: c.surname } 

四、排序和限制

限制語法:

LIMIT()

LIMIT后面跟着一個最大顯示數的數字,限制結果顯示行數。

FOR c IN Characters LIMIT 5 RETURN c.name

還可以使用LIMIT來跳過一定數量的記錄返回下一個n個文檔:

FOR c IN Characters LIMIT 2, 5 RETURN c.name

排序語法: 

SORT()    

DESC降序來反轉排序順序 

FOR c IN Characters SORT c.name DESC LIMIT 10 RETURN c.name

多個字段排序

FOR c IN Characters FILTER c.surname SORT c.surname, c.name LIMIT 10 RETURN { surname: c.surname, name: c.name }

此處FILTER的作用是僅保留surname為非空記錄

五、組合

語法:

MERGE()

MERGE()的功能是將對象組合在一起。因為使用了原始字符屬性{ traits: ... },所以后者被合並覆蓋。

FOR c IN Characters RETURN MERGE(c, { traits: DOCUMENT("Traits", c.traits)[*].en } )

六、圖操作

創建圖:

語法:

INSERT { _from: _id(A), _to: _id(B) } INTO ChildOf

實例:

首先,創建一個新的集合,並確保將集合類型更改為Edge。

然后,通過查詢多個集合的數據,將結果存入邊集合中

LET data = [                                                        //關系數據
 { "parent": { "name": "Ned", "surname": "Stark" }, "child": { "name": "Robb", "surname": "Stark" } }, { "parent": { "name": "Ned", "surname": "Stark" }, "child": { "name": "Sansa", "surname": "Stark" } }, { "parent": { "name": "Ned", "surname": "Stark" }, "child": { "name": "Arya", "surname": "Stark" } }, { "parent": { "name": "Ned", "surname": "Stark" }, "child": { "name": "Bran", "surname": "Stark" } }, { "parent": { "name": "Catelyn", "surname": "Stark" }, "child": { "name": "Robb", "surname": "Stark" } }, { "parent": { "name": "Catelyn", "surname": "Stark" }, "child": { "name": "Sansa", "surname": "Stark" } }, { "parent": { "name": "Catelyn", "surname": "Stark" }, "child": { "name": "Arya", "surname": "Stark" } }, { "parent": { "name": "Catelyn", "surname": "Stark" }, "child": { "name": "Bran", "surname": "Stark" } }, { "parent": { "name": "Ned", "surname": "Stark" }, "child": { "name": "Jon", "surname": "Snow" } }, { "parent": { "name": "Tywin", "surname": "Lannister" }, "child": { "name": "Jaime", "surname": "Lannister" } }, { "parent": { "name": "Tywin", "surname": "Lannister" }, "child": { "name": "Cersei", "surname": "Lannister" } }, { "parent": { "name": "Tywin", "surname": "Lannister" }, "child": { "name": "Tyrion", "surname": "Lannister" } }, { "parent": { "name": "Cersei", "surname": "Lannister" }, "child": { "name": "Joffrey", "surname": "Baratheon" } }, { "parent": { "name": "Jaime", "surname": "Lannister" }, "child": { "name": "Joffrey", "surname": "Baratheon" } } ] FOR rel in data LET parentId = FIRST(                                    //FIRST()提取第一個元素
 FOR c IN Characters FILTER c.name == rel.parent.name                    //篩選條件
            FILTER c.surname == rel.parent.surname LIMIT 1 RETURN c._id //返回_id
 ) LET childId = FIRST( FOR c IN Characters FILTER c.name == rel.child.name FILTER c.surname == rel.child.surname LIMIT 1 RETURN c._id ) FILTER parentId != null AND childId != null                        //剔除_id都為空的記錄
    INSERT { _from: childId, _to: parentId } INTO ChildOf       //將數據插入邊集合
    RETURN NEW                                                                   //返回數據 

也可以直接創建邊數據:

INSERT { _from: "Characters/robb", _to: "Characters/ned" } INTO ChildOf

遍歷圖:

語法:

FOR v IN 1..1 OUTBOUND _id ChildOf

    RETURN v.name

其中1..1為遍歷深度

實例:

FOR c IN Characters FILTER c.name == "Bran" FOR v IN 1..1 OUTBOUND c ChildOf RETURN v.name

返回

[ "Ned", "Catelyn" ]

遍歷的情況如下圖:

若是反向遍歷,則需要使用到INBOUND關鍵字:

FOR c IN Characters FILTER c.name == "Tywin" FOR v IN 2..2 INBOUND c ChildOf RETURN DISTINCT v.name

輸出:

[ "Joffrey" ] 

遍歷情況如下:

需要注意的是,“1..1”限制了遍歷深度為1,“2..2”限制了遍歷深度為2,而"1..2"限制遍歷深度既可以為1也可以為2。

七、地理空間查詢

地點數據

創建地點集合:

錄入地點數據:

LET places = [ { "name": "Dragonstone", "coordinate": [ 55.167801, -6.815096 ] }, { "name": "King's Landing", "coordinate": [ 42.639752, 18.110189 ] }, { "name": "The Red Keep", "coordinate": [ 35.896447, 14.446442 ] }, { "name": "Yunkai", "coordinate": [ 31.046642, -7.129532 ] }, { "name": "Astapor", "coordinate": [ 31.50974, -9.774249 ] }, { "name": "Winterfell", "coordinate": [ 54.368321, -5.581312 ] }, { "name": "Vaes Dothrak", "coordinate": [ 54.16776, -6.096125 ] }, { "name": "Beyond the wall", "coordinate": [ 64.265473, -21.094093 ] } ] FOR place IN places INSERT place INTO Locations

設置地理空間索引:

在COLLECTIONS界面,添加新的Indexes,設置為coordinate字段:

查找附近的位置

語法:

NEAR()

找到最接近的坐標參考點

FOR loc IN NEAR(Locations, 53.35, -6.26, 3) RETURN { name: loc.name, latitude: loc.coordinate[0], longitude: loc.coordinate[1] }

輸出:

[ { "name": "Vaes Dothrak", "latitude": 54.16776, "longitude": -6.096125 }, { "name": "Winterfell", "latitude": 54.368321, "longitude": -5.581312 }, { "name": "Dragonstone", "latitude": 55.167801, "longitude": -6.815096 } ]

查找半徑內的位置

語法:

WITHIN()  

從參考點搜索給定半徑內的位置

FOR loc IN WITHIN(Locations, 53.35, -6.26, 200 * 1000) RETURN { name: loc.name, latitude: loc.coordinate[0], longitude: loc.coordinate[1] }

輸出

[ { "name": "Vaes Dothrak", "latitude": 54.16776, "longitude": -6.096125 }, { "name": "Winterfell", "latitude": 54.368321, "longitude": -5.581312 } ]

按距離查找位置:

語法:

NEAR()或WITHIN()  

通過添加一個可選的第五個參數返回到參考點的距離。必須是一個字符串:

FOR loc IN NEAR(Locations, 53.35, -6.26, 3, "distance") RETURN { name: loc.name, latitude: loc.coordinate[0], longitude: loc.coordinate[1], distance: loc.distance / 1000 }

輸出:

[ { "name": "Vaes Dothrak", "latitude": 54.16776, "longitude": -6.096125, "distance": 91.56658640314431 }, { "name": "Winterfell", "latitude": 54.368321, "longitude": -5.581312, "distance": 121.66399816395028 }, { "name": "Dragonstone", "latitude": 55.167801, "longitude": -6.815096, "distance": 205.31879386198324 } ]

 使用AQL遇到的問題:

問題1:如何對查詢結果進行計數並返回?

解決方法:

RETURN COUNT(FOR v IN visitors FILTER v.ip == "127.0.0.1" RETURN 1)

 

 

參考資料:

https://docs.arangodb.com/3.3/AQL/Tutorial/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM