arango语法操作示例

1.CRUD 


Insert documents
INSERT document INTO collectionName

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


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

    
    
    
    
    
=========================================================
Read documents
=========================================================


FOR c IN Characters
    RETURN c
    

=========================================================
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"]
  }
]

=========================================================

=========================================================
Update documents
=========================================================

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


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

=========================================================

add a new attribute to all documents for instance:

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

=========================================================

=========================================================
Delete documents
=========================================================

REMOVE "2861650" IN Characters

=========================================================
FOR c IN Characters
    REMOVE c IN Characters

=========================================================


2.Match

=========================================================
Equality condition
=========================================================

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


=========================================================

FOR c IN Characters
    FILTER c.surname == "Stark"
    RETURN c


=========================================================




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

[
  "Joffrey",
  "Tyrion",
  "Samwell",
  "Ned",
  "Catelyn",
  "Cersei",
  "Jon",
  "Sansa",
  "Brienne",
  "Theon",
  "Davos",
  "Jaime",
  "Daenerys"
]

=========================================================

FOR c IN Characters
    FILTER c.age < 13
    RETURN { name: c.name, age: c.age }


[
  { "name": "Tommen", "age": null },
  { "name": "Arya", "age": 11 },
  { "name": "Roose", "age": null },
  ...
]

=========================================================





=========================================================
Multiple conditions
=========================================================
FOR c IN Characters
    FILTER c.age < 13
    FILTER c.age != null
    RETURN { name: c.name, age: c.age }

[
  { "name": "Arya", "age": 11 },
  { "name": "Bran", "age": 10 }
]

=========================================================

FOR c IN Characters
    FILTER c.age < 13 AND c.age != null
    RETURN { name: c.name, age: c.age }
-------------------------------------------------------------
And the second condition could as well be c.age > null.


=========================================================





=========================================================
Alternative conditions
=========================================================
FOR c IN Characters
    FILTER c.name == "Jon" OR c.name == "Joffrey"
    RETURN { name: c.name, surname: c.surname }
	
[
  { "name": "Joffrey", "surname": "Baratheon" },
  { "name": "Jon", "surname": "Snow" }
]
=========================================================

	

 

 

3.SORT


=========================================================
Cap the result count
=========================================================
FOR c IN Characters
    LIMIT 5
    RETURN c.name

[
  "Joffrey",
  "Tommen",
  "Tyrion",
  "Roose",
  "Tywin"
]

=========================================================
-----------------------------------------------
 allows you to skip a certain amount of record and return the next n documents
-----------------------------------------------
FOR c IN Characters
    LIMIT 2, 5
    RETURN c.name

[
  "Tyrion",
  "Roose",
  "Tywin",
  "Samwell",
  "Melisandre"
]

=========================================================




=========================================================
Sort by name
=========================================================

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

[
  "Arya",
  "Bran",
  "Brienne",
  "Bronn",
  "Catelyn",
  "Cersei",
  "Daario",
  "Daenerys",
  "Davos",
  "Ellaria"
]


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

[
  "Ygritte",
  "Viserys",
  "Varys",
  "Tywin",
  "Tyrion",
  "Tormund",
  "Tommen",
  "Theon",
  "The High Sparrow",
  "Talisa"
]





=========================================================



=========================================================
Sort by multiple attributes
=========================================================

-------------------------------------------------------------
Note that a filter is applied before sorting, to only let documents through, 
that actually feature a surname value (many don’t have it and would cause null values in the result)
--------------------------------------------------------------
FOR c IN Characters
    FILTER c.surname
    SORT c.surname, c.name
    LIMIT 10
    RETURN {
        surname: c.surname,
        name: c.name
    }
	
[
    { "surname": "Baelish", "name": "Petyr" },
    { "surname": "Baratheon", "name": "Joffrey" },
    { "surname": "Baratheon", "name": "Robert" },
    { "surname": "Baratheon", "name": "Stannis" },
    { "surname": "Baratheon", "name": "Tommen" },
    { "surname": "Bolton", "name": "Ramsay" },
    { "surname": "Bolton", "name": "Roose" },
    { "surname": "Clegane", "name": "Sandor" },
    { "surname": "Drogo", "name": "Khal" },
    { "surname": "Giantsbane", "name": "Tormund" }
]

=========================================================




=========================================================
Sort by age
=========================================================
FOR c IN Characters
    FILTER c.age
    SORT c.age
    LIMIT 10
    RETURN {
        name: c.name,
        age: c.age
    }

[
    { "name": "Bran", "age": 10 },
    { "name": "Arya", "age": 11 },
    { "name": "Sansa", "age": 13 },
    { "name": "Jon", "age": 16 },
    { "name": "Theon", "age": 16 },
    { "name": "Daenerys", "age": 16 },
    { "name": "Samwell", "age": 17 },
    { "name": "Joffrey", "age": 19 },
    { "name": "Tyrion", "age": 32 },
    { "name": "Brienne", "age": 32 }
]

=========================================================



4.JOIN

 

=============================================================
Importing traits
=============================================================
let data = [
    { "_key": "A", "en": "strong", "de": "stark" },
    { "_key": "B", "en": "polite", "de": "freundlich" },
    { "_key": "C", "en": "loyal", "de": "loyal" },
    { "_key": "D", "en": "beautiful", "de": "schön" },
    { "_key": "E", "en": "sneaky", "de": "hinterlistig" },
    { "_key": "F", "en": "experienced", "de": "erfahren" },
    { "_key": "G", "en": "corrupt", "de": "korrupt" },
    { "_key": "H", "en": "powerful", "de": "einflussreich" },
    { "_key": "I", "en": "naive", "de": "naiv" },
    { "_key": "J", "en": "unmarried", "de": "unverheiratet" },
    { "_key": "K", "en": "skillful", "de": "geschickt" },
    { "_key": "L", "en": "young", "de": "jung" },
    { "_key": "M", "en": "smart", "de": "klug" },
    { "_key": "N", "en": "rational", "de": "rational" },
    { "_key": "O", "en": "ruthless", "de": "skrupellos" },
    { "_key": "P", "en": "brave", "de": "mutig" },
    { "_key": "Q", "en": "mighty", "de": "mächtig" },
    { "_key": "R", "en": "weak", "de": "schwach" }
]
FOR d IN data
    INSERT d INTO Traits

=============================================================
Resolving traits
=============================================================

FOR c IN Characters
    RETURN c.traits

[
    { "traits": ["A","H","C","N","P"] },
    { "traits": ["D","H","C"] },
    ...
]
=============================================================

FOR c IN Characters
    RETURN DOCUMENT("Traits", c.traits)
	
[
  [
    {
      "_key": "A",
      "_id": "Traits/A",
      "_rev": "_V5oRUS2---",
      "en": "strong",
      "de": "stark"
    },
    {
      "_key": "H",
      "_id": "Traits/H",
      "_rev": "_V5oRUS6--E",
      "en": "powerful",
      "de": "einflussreich"
    },
    {
      "_key": "C",
      "_id": "Traits/C",
      "_rev": "_V5oRUS6--_",
      "en": "loyal",
      "de": "loyal"
    },
    {
      "_key": "N",
      "_id": "Traits/N",
      "_rev": "_V5oRUT---D",
      "en": "rational",
      "de": "rational"
    },
    {
      "_key": "P",
      "_id": "Traits/P",
      "_rev": "_V5oRUTC---",
      "en": "brave",
      "de": "mutig"
    }
  ],
  [
    {
      "_key": "D",
      "_id": "Traits/D",
      "_rev": "_V5oRUS6--A",
      "en": "beautiful",
      "de": "schön"
    },
    {
      "_key": "H",
      "_id": "Traits/H",
      "_rev": "_V5oRUS6--E",
      "en": "powerful",
      "de": "einflussreich"
    },
    {
      "_key": "C",
      "_id": "Traits/C",
      "_rev": "_V5oRUS6--_",
      "en": "loyal",
      "de": "loyal"
    }
  ],
  ...
]	
=============================================================

=============================================================
-------------------------------------------------------------
The DOCUMENT() function can be used to look up a single or multiple documents via document identifiers
In our example, we pass the collection name from which we want to fetch documents as first argument ("Traits") and an array of document keys (_key attribute) as second argument.
 In return we get an array of the full trait documents for each character.
-------------------------------------------------------------


FOR c IN Characters
    RETURN DOCUMENT("Traits", c.traits)[*].en
[
  [
    "strong",
    "powerful",
    "loyal",
    "rational",
    "brave"
  ],
  [
    "beautiful",
    "powerful",
    "loyal"
  ],
  ...
]
=============================================================




=============================================================
Merging characters and traits
=============================================================

---------------------------------------
merge both the character document and the data from the trait documents

The MERGE() functions merges objects together. 
Because we used an object { traits: ... } which has the same attribute name traits as the original character attribute, 
the latter got overwritten by the merge operation.
---------------------------------------

FOR c IN Characters
    RETURN MERGE(c, { traits: DOCUMENT("Traits", c.traits)[*].en } )
	
[
  {
    "_id": "Characters/2861650",
    "_key": "2861650",
    "_rev": "_V1bzsXa---",
    "age": 41,
    "alive": false,
    "name": "Ned",
    "surname": "Stark",
    "traits": [
      "strong",
      "powerful",
      "loyal",
      "rational",
      "brave"
    ]
  },
  {
    "_id": "Characters/2861653",
    "_key": "2861653",
    "_rev": "_V1bzsXa--B",
    "age": 40,
    "alive": false,
    "name": "Catelyn",
    "surname": "Stark",
    "traits": [
      "beautiful",
      "powerful",
      "loyal"
    ]
  },
  ...
]
=============================================================




=============================================================
Join another way
=============================================================
FOR c IN Characters
  RETURN MERGE(c, {
    traits: (
      FOR key IN c.traits
        FOR t IN Traits
          FILTER t._key == key
          RETURN t.en
    )
  })
  
=============================================================

5.graph travel

 

=========================================================
Traversal
=========================================================
---------------------------------------------------------
In ArangoDB, two documents (a parent and a child character document) can be linked by an edge document.
Edge documents are stored in edge collections and have two additional attributes: _from and _to. 
They reference any two documents by their document IDs (_id).
---------------------------------------------------------


=========================================================
ChildOf relations
=========================================================	

  Robb -> Ned
   Sansa -> Ned
    Arya -> Ned
    Bran -> Ned
     Jon -> Ned
    Robb -> Catelyn
   Sansa -> Catelyn
    Arya -> Catelyn
    Bran -> Catelyn
   Jaime -> Tywin
  Cersei -> Tywin
  Tyrion -> Tywin
 Joffrey -> Jaime
 Joffrey -> Cersei

=========================================================




=========================================================
Creating the edges
=========================================================
----------------------------------------------------------
To create the required edge documents to store these relations in the database, 
we can run a query that combines joining and filtering to match up the right character documents,
 then use their _id attribute to insert an edge into an edge collection ChildOf.
----------------------------------------------------------


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(
        FOR c IN Characters
            FILTER c.name == rel.parent.name
            FILTER c.surname == rel.parent.surname
            LIMIT 1
            RETURN c._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
    INSERT { _from: childId, _to: parentId } INTO ChildOf
    RETURN NEW

--------------------------------------------------------------
The character documents don’t have user-defined keys. 
If they had, it would allow us to create the edges more easily like:

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


=========================================================
Traverse to the parents
=========================================================
--------------------------------
 we have a graph we can query to find out who the parents are of another character – or in graph terms,
 we want to start at a vertex and follow the edges to other vertices in an AQL graph traversal:
 ------------------------------
 FOR v IN 1..1 OUTBOUND "Characters/2901776" ChildOf
    RETURN v.name
	



FOR c IN Characters
    FILTER c.name == "Bran"
    RETURN c._id

[ "Characters/<YourDocumentkey>" ]

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

[
  "Ned",
  "Catelyn"
]
=========================================================




=========================================================
Traverse to the children
=========================================================
FOR c IN Characters
    FILTER c.name == "Ned"
    FOR v IN 1..1 INBOUND c ChildOf
        RETURN v.name
[
  "Robb",
  "Sansa",
  "Jon",
  "Arya",
  "Bran"
]	

=========================================================




=========================================================
Traverse to the grandchildren
=========================================================
FOR c IN Characters
    FILTER c.name == "Tywin"
    FOR v IN 2..2 INBOUND c ChildOf
        RETURN v.name

[
  "Joffrey",
  "Joffrey"
]		
		
Tywin <- Jaime <- Joffrey
Tywin <- Cersei <- Joffrey
=========================================================


=========================================================
Traverse with variable depth
=========================================================

-------------------------------------------------------------------
To return the parents and grandparents of Joffrey, 
we can walk edges in OUTBOUND direction and adjust the traversal depth to go at least 1 step, and 2 at most:
-------------------------------------------------------------------
FOR c IN Characters
    FILTER c.name == "Joffrey"
    FOR v IN 1..2 OUTBOUND c ChildOf
        RETURN DISTINCT v.name

[
  "Cersei",
  "Tywin",
  "Jaime"
]

=========================================================






6.OPERATORS

=========================================================
Comparison operators
=========================================================
The following comparison operators are supported:

== equality
!= inequality
< less than
<= less or equal
> greater than
>= greater or equal
IN test if a value is contained in an array
NOT IN test if a value is not contained in an array
LIKE tests if a string value matches a pattern
=~ tests if a string value matches a regular expression
!~ tests if a string value does not match a regular expression


=========================================================
----------------------------------------------------------
比较操作符接受第一和第二操作数的任何数据类型。
但是,IN和NOT IN只在它们的右操作数是数组时返回有意义的结果,
而LIKE只在两个操作数都是字符串值时执行。
如果比较操作数具有不同的或不可感知的类型,则比较操作符不会执行任何隐式类型转换。
----------------------------------------------------------
0 == null                 // false
1 > 0                     // true
true != null              // true
45 <= "yikes!"            // true
65 != "65"                // true
65 == 65                  // true
1.23 > 1.32               // false
1.5 IN [ 2, 3, 1.5 ]      // true
"foo" IN null             // false
42 NOT IN [ 17, 40, 50 ]  // true
"abc" == "abc"            // true
"abc" == "ABC"            // false
"foo" LIKE "f%"           // true
"foo" =~ "^f[o].$"        // true
"foo" !~ "[a-z]+bar$"     // true


=========================================================
----------------------------------------------------------
LIKE操作符检查其左操作数是否匹配其右操作数中指定的模式。
模式可以由正则字符和通配符组成。
所支持的通配符是_,用于匹配单个任意字符,%用于匹配任意数量的任意字符。文字%和_需要用反斜杠转义。
反斜杠本身需要转义,这实际上意味着两个反向solidus字符需要放在百分比符号或下划线的前面。
在arangosh中,需要额外的转义,使它在要转义的字符之前总共有四个反斜杠。
----------------------------------------------------------
"abc" LIKE "a%"              // true
"abc" LIKE "_bc"             // true
"a_b_foo" LIKE "a\\_b\\_foo" // true


=========================================================
Array comparison operators
=========================================================

[ 1, 2, 3 ] ALL IN [ 2, 3, 4 ]   // false
[ 1, 2, 3 ] ALL IN [ 1, 2, 3 ]   // true
[ 1, 2, 3 ] NONE IN [ 3 ]        // false
[ 1, 2, 3 ] NONE IN [ 23, 42 ]   // true
[ 1, 2, 3 ] ANY IN [ 4, 5, 6 ]   // false
[ 1, 2, 3 ] ANY IN [ 1, 42 ]     // true
[ 1, 2, 3 ] ANY == 2             // true
[ 1, 2, 3 ] ANY == 4             // false
[ 1, 2, 3 ] ANY > 0              // true
[ 1, 2, 3 ] ANY <= 1             // true
[ 1, 2, 3 ] NONE < 99            // false
[ 1, 2, 3 ] NONE > 10            // true
[ 1, 2, 3 ] ALL > 2              // false
[ 1, 2, 3 ] ALL > 0              // true
[ 1, 2, 3 ] ALL >= 3             // false
["foo", "bar"] ALL != "moo"      // true
["foo", "bar"] NONE == "bar"     // false
["foo", "bar"] ANY == "foo"      // true


=========================================================
Logical operators
=========================================================

Logical operators
The following logical operators are supported in AQL:

&& logical and operator
|| logical or operator
!  logical not/negation operator
AQL also supports the following alternative forms for the logical operators:

AND logical and operator
OR  logical or operator
NOT logical not/negation operator


=========================================================
Arithmetic operators
=========================================================
AQL supports the following arithmetic operators:

+	 addition
- 	subtraction
* 	multiplication
/ 	division
% 	modulus
Unary plus and unary minus are supported as well:

LET x = -5
LET y = 1
RETURN [-x, +y]
// [5, 1]



=========================================================

算术运算符接受任何类型的操作数。将非数值值传递给算术运算符将使用TO_NUMBER()函数应用的类型转换规则将操作数转换为数字:
null将被转换为0
false将被转换为0,true将被转换为1
一个有效的数值保持不变,但是NaN和Infinity将被转换为0
如果字符串值包含数字的有效字符串表示形式,则将其转换为数字。字符串开头或结尾的任何空格都将被忽略。包含其他内容的字符串被转换为数字0
将空数组转换为0,将具有一个成员的数组转换为其唯一成员的数字表示形式。具有更多成员的数组被转换为数字0。
对象/文档被转换为数字0。


1 + "a"                 // 1
1 + "99"                // 100
1 + null                // 1
null + 1                // 1
3 + [ ]                 // 3
24 + [ 2 ]              // 26
24 + [ 2, 4 ]           // 0
25 - null               // 25
17 - true               // 16
23 * { }                // 0
5 * [ 7 ]               // 35
24 / "12"               // 2
1 / 0                   // 0
=========================================================





=========================================================
Ternary operator
=========================================================
三元运算符期望布尔条件作为其第一个操作数,如果条件的值为true,则返回第二个操作数的结果,否则返回第三个操作数的结果。
Examples

u.age > 15 || u.active == true ? u.userId : null



=========================================================
Range operator
=========================================================
The .. operator will produce an array of the integer values in the defined range, with both bounding values included.
Examples

2010..2013
will produce the following result:

[ 2010, 2011, 2012, 2013 ]


=========================================================
Operator precedence
=========================================================
The operator precedence in AQL is similar as in other familiar languages (lowest precedence first):



? : ternary operator
|| logical or
&& logical and
**, != equality and inequality
IN in operator
<, <=, >=, > less than, less equal, greater equal, greater than
+, - addition, subtraction
*, /, % multiplication, division, modulus
!, +, - logical negation, unary plus, unary minus
[*] expansion
() function call
. member access
[] indexed value access


=========================================================

7.DATA QUERY

=========================================================
Data Access Queries

=========================================================
RETURN "Hello ArangoDB!"

--可以调用函数DOCUMENT()通过它的文档句柄检索单个文档,例如:
RETURN DOCUMENT("users/phil")

=========================================================
FOR doc IN users
    RETURN doc
----------------------------------------------------------

FOR doc IN users
    RETURN { user: doc, newAttribute: true }
----------------------------------------------------------
FOR doc IN users
    FILTER doc._key == "phil"
    RETURN doc
----------------------------------------------------------
FOR doc IN users
    FILTER doc.status == "active"
    SORT doc.name
    LIMIT 10
=========================================================



=========================================================
Data Modification Queries
=========================================================
INSERT: insert new documents into a collection
UPDATE: partially update existing documents in a collection
REPLACE: completely replace existing documents in a collection
REMOVE: remove existing documents from a collection
UPSERT: conditionally insert or update documents in a collection



=========================================================
Modifying a single document
=========================================================
INSERT {
    firstName: "Anna",
    name: "Pavlova",
    profession: "artist"
} IN users

INSERT {
    _key: "GilbertoGil",
    firstName: "Gilberto",
    name: "Gil",
    city: "Fortalezza"
} IN users

INSERT {
    _key: "PhilCarpenter",
    firstName: "Phil",
    name: "Carpenter",
    middleName: "G.",
    status: "inactive"
} IN users

INSERT {
    _key: "NatachaDeclerck",
    firstName: "Natacha",
    name: "Declerck",
    location: "Antwerp"
} IN users 


UPDATE "PhilCarpenter" WITH {
    status: "active",
    location: "Beijing"
} IN users

--Replace是替换文档所有属性的update的替代方法。

REPLACE {
    _key: "NatachaDeclerck",
    firstName: "Natacha",
    name: "Leclerc",
    status: "active",
    level: "premium"
} IN users


--Removing a document if you know its key is simple as well :

REMOVE "GilbertoGil" IN users
REMOVE { _key: "GilbertoGil" } IN users
=========================================================




=========================================================
Modifying multiple documents
=========================================================
FOR u IN users
    FILTER u.status == "not active"
    UPDATE u WITH { status: "inactive" } IN users

	
FOR u IN users
    INSERT u IN backup

	
FOR u IN users
    FILTER u.status == "deleted"
    REMOVE u IN backup
	
--The following example will remove all documents from both users and backup:

LET r1 = (FOR u IN users  REMOVE u IN users)
LET r2 = (FOR u IN backup REMOVE u IN backup)
RETURN true
=========================================================





=========================================================
Returning documents
=========================================================
数据修改查询可以选择返回文档。
为了在返回语句中引用插入、删除或修改的文档,数据修改语句引入了旧的和/或新的伪值:

FOR i IN 1..100
    INSERT { value: i } IN test 
    RETURN NEW

FOR u IN users
    FILTER u.status == "deleted"
    REMOVE u IN users 
    RETURN OLD
	
FOR u IN users
    FILTER u.status == "not active"
    UPDATE u WITH { status: "inactive" } IN users 
    RETURN NEW
	
FOR i IN 1..100
    INSERT { value: i } IN test 
    RETURN NEW._key
	
--Using OLD and NEW in the same query

FOR u IN users
    FILTER u.status == "not active"
    UPDATE u WITH { status: "inactive" } IN users 
    RETURN { old: OLD, new: NEW }


--Calculations with OLD or NEW
--例如,下面的查询执行upsert操作,是更新了现有文档,还是插入了新文档。
--它通过在UPSERT之后,检查旧变量并使用LET语句存储操作类型的临时字符串来实现:

UPSERT { name: "test" }
    INSERT { name: "test" }
    UPDATE { } IN users
LET opType = IS_NULL(OLD) ? "insert" : "update"
RETURN { _key: NEW._key, type: opType }
	
=========================================================


在集群中,AQL数据修改查询目前不以事务方式执行。
此外,update、replace、upsert和remove AQL查询目前要求为所有应该修改或删除的文档指定_key属性,即使为集合选择了除_key之外的共享密钥属性。
这个限制可以在ArangoDB的未来版本中克服



=========================================================





=========================================================

 

 9.HIGH-LEVEL OPERATORS

 

=========================================================
FOR
=========================================================
FOR variableName IN expression

FOR vertexVariableName, edgeVariableName, pathVariableName IN traversalExpression

FOR u IN users
  RETURN u

FOR year IN [ 2011, 2012, 2013 ]
  RETURN { "year" : year, "isLeapYear" : year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) }
  
FOR u IN users
  FOR l IN locations
    RETURN { "user" : u, "location" : l }


=========================================================
RETURN
=========================================================
RETURN expression

FOR variableName IN expression
  RETURN variableName


FOR u IN users
  RETURN u


 FOR u IN users
  RETURN u.name

  
FOR u IN users
  RETURN { name: u.name, age: u.age }


FOR u IN users
  RETURN { [ u._id ]: u.age }  

[
  {
    "users/9883": 32
  },
  {
    "users/9915": 27
  },
  {
    "users/10074": 69
  }
]

--对于一个将用户id映射到年龄的单一对象,需要将单个结果与另一个返回合并并返回
RETURN MERGE(
  FOR u IN users
    RETURN { [ u._id ]: u.age }
)

[
  {
    "users/10074": 69,
    "users/9883": 32,
    "users/9915": 27
  }
]

=========================================================



=========================================================
RETURN DISTINCT
=========================================================
FOR variableName IN expression
  RETURN DISTINCT expression

FOR what IN 1..2
  RETURN DISTINCT (
    FOR i IN [ 1, 2, 3, 4, 1, 3 ] 
      RETURN i
  )
  
[
  [ 1, 2, 3, 4, 1, 3 ]
]
=========================================================






=========================================================
FILTER
=========================================================

FOR u IN users
  FILTER u.active == true && u.age < 39
  RETURN u

  
FOR u IN users
  FILTER u.active == true
  FILTER u.age < 39
  RETURN u
  
  
FOR u IN users
  FILTER u.active == true
  RETURN u
  
  
FOR u IN users
  FILTER u.active == true
  LIMIT 5
  RETURN u
  
  
FOR u IN users
  FILTER u.active == true
  LIMIT 5
  FILTER u.gender == "f"
  RETURN u

  
FOR u IN users
  FILTER u.active == true
  SORT u.age ASC
  LIMIT 5
  FILTER u.gender == "f"
  RETURN u  
=========================================================




=========================================================
SORT
=========================================================
FOR u IN users
  SORT u.lastName, u.firstName, u.id DESC
  RETURN u
  
=========================================================



=========================================================
LIMIT
=========================================================
LIMIT count
LIMIT offset, count

FOR u IN users
  LIMIT 5
  RETURN u
  

FOR u IN users
  SORT u.firstName, u.lastName, u.id DESC
  LIMIT 2, 5
  RETURN u

=========================================================


=========================================================
LET
=========================================================
LET variableName = expression

LET a = [1, 2, 3]  // initial assignment

a = PUSH(a, 4)     // syntax error, unexpected identifier
LET a = PUSH(a, 4) // parsing error, variable 'a' is assigned multiple times
LET b = PUSH(a, 4) // allowed, result: [1, 2, 3, 4]


FOR u IN users
  LET numRecommendations = LENGTH(u.recommendations)
  RETURN { 
    "user" : u, 
    "numRecommendations" : numRecommendations, 
    "isPowerUser" : numRecommendations >= 10 
  } 
  

FOR u IN users
  LET friends = (
  FOR f IN friends 
    FILTER u.id == f.userId
    RETURN f
  )
  LET memberships = (
  FOR m IN memberships
    FILTER u.id == m.userId
      RETURN m
  )
  RETURN { 
    "user" : u, 
    "friends" : friends, 
    "numFriends" : LENGTH(friends), 
    "memberShips" : memberships 
  }

=========================================================


=========================================================
COLLECT
The COLLECT keyword can be used to group an array by one or multiple group criteria.
=========================================================
COLLECT的第一种语法形式仅根据表达式中指定的已定义的组标准对结果进行分组。
为了进一步处理COLLECT产生的结果,引入了一个新的变量(由variableName指定)。这个变量包含组值。
下面是一个示例查询,它在u中查找不同的值。并在不同的城市提供:


=========================================================

--The general syntaxes for COLLECT are:

COLLECT variableName = expression options
COLLECT variableName = expression INTO groupsVariable options
COLLECT variableName = expression INTO groupsVariable = projectionExpression options
COLLECT variableName = expression INTO groupsVariable KEEP keepVariable options
COLLECT variableName = expression WITH COUNT INTO countVariable options
COLLECT variableName = expression AGGREGATE variableName = aggregateExpression options
COLLECT AGGREGATE variableName = aggregateExpression options
COLLECT WITH COUNT INTO countVariable options


FOR u IN users
  COLLECT city = u.city
  RETURN { 
    "city" : city 
  }
  
  
FOR u IN users
  COLLECT city = u.city INTO groups
  RETURN { 
    "city" : city, 
    "usersInCity" : groups 
  }
  
  
FOR u IN users
  COLLECT country = u.country, city = u.city INTO groups
  RETURN { 
    "country" : country, 
    "city" : city, 
    "usersInCity" : groups 
  }
  
  
FOR u IN users
  COLLECT country = u.country, city = u.city INTO groups = u.name
  RETURN { 
    "country" : country, 
    "city" : city, 
    "userNames" : groups 
  }
  
  

FOR u IN users
  COLLECT country = u.country, city = u.city INTO groups = { 
    "name" : u.name, 
    "isActive" : u.status == "active"
  }
  RETURN { 
    "country" : country, 
    "city" : city, 
    "usersInCity" : groups 
  }
  
  
--KEEP仅与INTO组合时有效。在KEEP子句中只能使用有效的变量名。KEEP支持指定多个变量名。
FOR u IN users
  LET name = u.name
  LET someCalculation = u.value1 + u.value2
  COLLECT city = u.city INTO groups KEEP name 
  RETURN { 
    "city" : city, 
    "userNames" : groups[*].name 
  }

--COLLECT还提供了一个特殊的WITH COUNT子句,可用来有效地确定组成员的数量。
FOR u IN users
  COLLECT WITH COUNT INTO length
  RETURN length
 
--WITH COUNT子句只能与INTO子句一起使用。 
FOR u IN users
  COLLECT age = u.age WITH COUNT INTO length
  RETURN { 
    "age" : age, 
    "count" : length 
  }


=========================================================
Aggregation
=========================================================

--可以使用COLLECT语句对每个组执行数据聚合。
--为了只确定组长度,可以使用前面描述的COLLECT的WITH COUNT INTO变体。
--对于其他聚合,可以对收集的结果运行聚合函数

FOR u IN users
  COLLECT ageGroup = FLOOR(u.age / 5) * 5 INTO g
  RETURN { 
    "ageGroup" : ageGroup,
    "minAge" : MIN(g[*].u.age),
    "maxAge" : MAX(g[*].u.age)
  }
 

--上面的方法要求在对所有组的collect操作期间存储所有组的值,这可能是低效的。
--COLLECT的特殊聚合变体允许在COLLECT操作期间增量地构建聚合值,因此通常效率更高。
--使用聚合变量,上面的查询变成:
FOR u IN users
  COLLECT ageGroup = FLOOR(u.age / 5) * 5 
  AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
  RETURN {
    ageGroup, 
    minAge, 
    maxAge 
  }
  
  
--聚合关键字只能在COLLECT关键字之后使用。如果使用,它必须直接遵循分组键的声明。如果没有使用分组键,则必须直接跟随COLLECT关键字:
FOR u IN users
  COLLECT AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
  RETURN {
    minAge, 
    maxAge 
  }
  
FOR u IN users
  COLLECT AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age), sumAge = SUM(u.age)
  RETURN {
    minAge, 
    maxAge, 
    sumAge
  }
  

--在顶层,聚合表达式必须是对受支持的聚合函数之一)的调用。
--(LENGTH、MIN、MAX、SUM、AVERAGE、STDDEV_POPULATION、STDDEV_SAMPLE、VARIANCE_POPULATION、VARIANCE_SAMPLE、UNIQUE、SORTED_UNIQUE或COUNT_DISTINCT
--也允许使用以下别名:COUNT(用于长度)、AVG(用于平均值)、STDDEV(用于STDDEV_POPULATION)、VARIANCE(用于VARIANCE_POPULATION)、COUNT_UNIQUE(用于COUNT_DISTINCT)。
--聚合表达式不能引用COLLECT本身引入的变量。

=========================================================
Setting COLLECT options
=========================================================

可以在COLLECT语句中使用选项来通知优化器有关首选的COLLECT方法。
当为COLLECT语句指定以下附录时,优化器将始终使用已排序的COLLECT变体,甚至不会使用hash变体创建计划:

OPTIONS { method: "sorted" }

也可以指定hash作为首选方法。在这种情况下,优化器只有在COLLECT语句符合条件时才会使用散列方法创建计划(不是所有的COLLECT语句都可以使用散列方法)。如果COLLECT语句符合条件,则只有一个计划使用散列方法。如果不符合条件,优化器将使用排序的方法。


=========================================================
COLLECT vs. RETURN DISTINCT
=========================================================
为了使结果集惟一,可以使用COLLECT或RETURN DISTINCT。在幕后,这两种变体都将通过创建AggregateNode来工作。对于这两种变体,优化器都可以尝试COLLECT的排序变体和散列变体。因此,区别主要在于语法,与等效的COLLECT相比,RETURN明显节省了一些输入:

FOR u IN users
  RETURN DISTINCT u.age
  
  
FOR u IN users
  COLLECT age = u.age
  RETURN age
  
然而,COLLECT比RETURN DISTINCT灵活得多。此外,对于不同的返回,结果的顺序是未定义的,而对于COLLECT,结果将排序。





===========================================================
REMOVE
===========================================================

REMOVE keyExpression IN collection options

--集合必须包含要从中删除文档的集合的名称。keyExpression必须是包含文档标识的表达式。它可以是字符串(然后必须包含文档键),也可以是文档(必须包含_key属性)。

FOR u IN users
  REMOVE { _key: u._key } IN users

FOR u IN users
  REMOVE u._key IN users

FOR u IN users
  REMOVE u IN users

--删除操作可以删除任意文件,且该文件不需要与前一个FOR语句生成的文件相同:
FOR i IN 1..1000
  REMOVE { _key: CONCAT('test', i) } IN users

FOR u IN users
  FILTER u.active == false
  REMOVE { _key: u._key } IN backup

--也可以删除单个文档,使用文档键字符串或具有_key属性的文档:
REMOVE 'john' IN users

LET doc = DOCUMENT('users/john')
REMOVE doc IN users


--如果其中一个待删除文档不存在,下面的查询将会失败:
FOR i IN 1..1000
  REMOVE { _key: CONCAT('test', i) } IN users
  
  
--通过指定ignoreErrors查询选项,可以抑制这些错误,这样查询就完成了:
FOR i IN 1..1000
  REMOVE { _key: CONCAT('test', i) } IN users OPTIONS { ignoreErrors: true }

  
--为了确保查询返回时数据已被写入磁盘,有waitForSync查询选项:
FOR i IN 1..1000
  REMOVE { _key: CONCAT('test', i) } IN users OPTIONS { waitForSync: true }
  
FOR i IN 1..1000
  REMOVE { _key: CONCAT('test', i), _rev: "1287623" } IN users OPTIONS { ignoreRevs: false }

  
===========================================================
 Returning the removed documents
===========================================================
FOR u IN users
  REMOVE u IN users 
  LET removed = OLD 
  RETURN removed._key
  
  
======================================================================================================================
======================================================================================================================
UPDATE
======================================================================================================================
======================================================================================================================

UPDATE document IN collection options
UPDATE keyExpression WITH document IN collection options


FOR u IN users
  UPDATE { _key: u._key, name: CONCAT(u.firstName, " ", u.lastName) } IN users
  
FOR u IN users
  UPDATE { name: CONCAT(u.firstName, " ", u.lastName) } IN users
  
  
--集合必须包含要更新文档的集合的名称。文档必须是包含要更新的属性和值的文档。
--在使用第一个语法时,document还必须包含_key属性,以标识要更新的文档。
FOR u IN users
  UPDATE { _key: u._key, name: CONCAT(u.firstName, " ", u.lastName) } IN users
  
  
--有_id属性但没有_key属性的对象以及像“users/john”这样的字符串一样的文档ID不能工作。
--但是,您可以使用DOCUMENT(id)通过它的id和PARSE_IDENTIFIER(id)来获取文档。获取作为字符串的文档密钥。
FOR u IN users
  UPDATE u._key WITH { name: CONCAT(u.firstName, " ", u.lastName) } IN users

FOR u IN users
  UPDATE { _key: u._key } WITH { name: CONCAT(u.firstName, " ", u.lastName) } IN users

FOR u IN users
  UPDATE u WITH { name: CONCAT(u.firstName, " ", u.lastName) } IN users
  
  
 --更新操作可更新不需要与前一个FOR语句生成的文档相同的任意文档:
 FOR i IN 1..1000
  UPDATE CONCAT('test', i) WITH { foobar: true } IN users

FOR u IN users
  FILTER u.active == false
  UPDATE u WITH { status: 'inactive' } IN backup
  
  
--Using the current value of a document attribute
--WITH子句中不支持伪变量OLD(更新后可用)。要访问当前属性值,通常可以通过FOR循环的变量引用文档,FOR循环用于遍历集合
FOR doc IN users
  UPDATE doc WITH {
    fullName: CONCAT(doc.firstName, " ", doc.lastName)
  } IN users

  
--如果没有循环,因为只更新一个文档,那么可能没有像上面这样的变量(doc),让您引用正在更新的文档:
UPDATE "john" WITH { ... } IN users
 
LET key = PARSE_IDENTIFIER("users/john").key
UPDATE key WITH { ... } IN users
  
  
--要在这种情况下访问当前值,必须首先检索文档并将其存储在一个变量中:
LET doc = DOCUMENT("users/john")
UPDATE doc WITH {
  fullName: CONCAT(doc.firstName, " ", doc.lastName)
} IN users


--现有属性可以根据其当前值进行修改,例如:
UPDATE doc WITH {
  karma: doc.karma + 1
} IN users


--If the attribute hobbies doesn’t exist yet, 
--it is conveniently initialized as [ "swimming" ] and otherwise extended. 
UPDATE doc WITH {
  hobbies: PUSH(doc.hobbies, "swimming")
} IN users
 
 
 
 
====================================================
Setting query options
====================================================

FOR i IN 1..1000
  UPDATE {
    _key: CONCAT('test', i)
  } WITH {
    foobar: true
  } IN users OPTIONS { ignoreErrors: true }
  
  
更新操作只更新文档中指定的属性,而不修改其他属性。内部属性(如_id、_key、_rev、_from和_to)不能更新,并且在文档中指定时将被忽略。更新文档将使用服务器生成的值修改文档的修订号。
当使用空值更新属性时,ArangoDB不会从文档中删除该属性,而是为其存储空值。若要在更新操作中删除属性,请将其设置为null并提供keepNull选项:

FOR u IN users
  UPDATE u WITH {
    foobar: true,
    notNeeded: null
  } IN users OPTIONS { keepNull: false }

  
  
  
====================================================
Returning the modified documents
====================================================  


UPDATE document IN collection options RETURN OLD
UPDATE document IN collection options RETURN NEW
UPDATE keyExpression WITH document IN collection options RETURN OLD
UPDATE keyExpression WITH document IN collection options RETURN NEW


FOR u IN users
  UPDATE u WITH { value: "test" }
  IN users 
  LET previous = OLD 
  RETURN previous._key
  
FOR u IN users
  UPDATE u WITH { value: "test" } 
  IN users
  LET updated = NEW 
  RETURN UNSET(updated, "_key", "_id", "_rev")
  
FOR u IN users
  UPDATE u WITH { value: "test" } 
  IN users
  RETURN { before: OLD, after: NEW }
 
======================================================================================================================
======================================================================================================================
REPLACE
======================================================================================================================
======================================================================================================================
REPLACE document IN collection options
REPLACE keyExpression WITH document IN collection options

--集合必须包含要替换文档的集合的名称。文档是替换文档。当使用第一个语法时,document还必须包含_key属性来标识要替换的文档。
FOR u IN users
  REPLACE { _key: u._key, name: CONCAT(u.firstName, u.lastName), status: u.status } IN users

--The following query is invalid because it does not contain a _key attribute and thus it is not possible to determine the documents to be replaced:
FOR u IN users
  REPLACE { name: CONCAT(u.firstName, u.lastName, status: u.status) } IN users
  
--当使用第二种语法时,keyExpression提供文档标识。它可以是字符串(然后必须包含文档键),也可以是文档(必须包含_key属性)。
FOR u IN users
  REPLACE { _key: u._key, name: CONCAT(u.firstName, u.lastName) } IN users

FOR u IN users
  REPLACE u._key WITH { name: CONCAT(u.firstName, u.lastName) } IN users

FOR u IN users
  REPLACE { _key: u._key } WITH { name: CONCAT(u.firstName, u.lastName) } IN users

FOR u IN users
  REPLACE u WITH { name: CONCAT(u.firstName, u.lastName) } IN users
  
  
  
======================================================================================================================
======================================================================================================================
INSERT
======================================================================================================================
======================================================================================================================

INSERT document INTO collection [ OPTIONS options ]


FOR i IN 1..100
  INSERT { value: i } INTO numbers
  
  
INSERT { value: 1 } INTO numbers


FOR u IN users
  FOR p IN products
    FILTER u._key == p.recommendedBy
    INSERT { _from: u._id, _to: p._id } INTO recommendations
	
	

--Setting query options

--忽略错误
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { ignoreErrors: true }
  
 -- waitForSync true, 确保已经插入才返回
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { waitForSync: true }
  
--插入时,若已存在相同的key,则重写
FOR i IN 1..1000
  INSERT {
    _key: CONCAT('test', i),
    name: "test",
    foobar: true
  } INTO users OPTIONS { overwrite: true }
 
  
--Returning the inserted documents
INSERT document INTO collection RETURN NEW

FOR i IN 1..100
  INSERT { value: i }
  INTO users
  LET inserted = NEW
  RETURN inserted._key

  
======================================================================================================================
======================================================================================================================
UPSERT
======================================================================================================================
======================================================================================================================
UPSERT searchExpression INSERT insertExpression UPDATE updateExpression IN collection options
UPSERT searchExpression INSERT insertExpression REPLACE updateExpression IN collection options


UPSERT { name: 'superuser' } 
INSERT { name: 'superuser', logins: 1, dateCreated: DATE_NOW() } 
UPDATE { logins: OLD.logins + 1 } IN users


-------------------------------------------------------------------------------------------------------------
FOR i IN 1..1000
  UPSERT { _key: CONCAT('test', i)}
    INSERT {foobar: false}
    UPDATE {_rev: "1287623", foobar: true }
  IN users OPTIONS { ignoreRevs: false }
  
  

======================================================================================================================
======================================================================================================================
WITH
======================================================================================================================
======================================================================================================================
  
AQL查询可以选择从with语句和查询使用的集合列表开始。除了查询使用的其他集合和由AQL查询解析器检测到的集合之外,WITH中指定的所有集合在查询开始时都将被读锁定。
对于动态访问集合的查询(例如通过遍历或通过document()之类的动态文档访问函数),在WITH中指定进一步的集合可能很有用。
这样的集合可能在查询编译时对AQL查询解析器不可见,因此在查询开始时不会被自动读锁定。
在这种情况下,无论何时使用这些集合,AQL执行引擎都会惰性地锁定它们,这可能导致与其他查询发生死锁
。如果检测到这样的死锁,查询将自动中止并回滚更改。在这种情况下,客户机应用程序可以尝试再次发送查询。
但是,如果客户机应用程序为所有使用WITH的查询指定使用的集合列表,则不会发生死锁,也不会因为死锁情况而中止查询。

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值