ArrangoDB文档/By aakz0347

四、数据查询

(一)数据访问查询
FOR doc IN users   /*user是一个集合*/
    RETURN doc

/*可以添加FILTER, SORT, LIMIT等操作*/
FOR doc IN users
  FILTER doc._key == "phil"
  RETURN doc

 FOR doc IN users
  FILTER doc.status == "active"
  SORT doc.name
  LIMIT 10
/*一般的使用顺序是,LIMIT放在最后,在FILTER, SORT等操作之后*/ 
(二)数据修改查询
INSERT:将新文档插入集合
UPDATE:部分更新集合中的现有文档
REPLACE:完全替换集合中的现有文档
REMOVE:从集合中删除现有文档
UPSERT:有条件地插入或更新集合中的文档

执行查询之前,需要先创建好集合(以users为例)

INSRT{
    _key: "PhilCarpenter"
    firstName: "Anna",
    name: "Pavlova",
    profession: "artist"
    status: "active"
}INTO users

更改status属性并添加location属性:

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

REPLACE操作是UPDATE操作的变体,替换掉文档的所有属性

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

REMOVE操作通过文档键key来识别:

REMOVE "NatachaDeclerck" IN users
(三)修改多个文件
/*创建多个文件:insert+for*/
FOR i IN 1..1000
  INSERT {
    id: 100000 + i,
    age: 18 + FLOOR(RAND() * 25),
    name: CONCAT('test', TO_STRING(i)),
    status: i % 2 == 0 ? "active" : "not active",
    active: false,
    gender: i % 3 == 0 ? "male" : i % 3 == 1 ? "female" : "diverse"
  } IN users
/*修改多个文件:update+for*/
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.staus == "deleted"
    REMOVE u IN backup

/*删除集合所有内容*/
FOR u IN users
    REMOVE u IN users

1.对于较大的对象和数组,可以通过HASH()进行比较操作

2.RETURN OLD / RETURN NEW 返回修改前/修改后的值

/*部分返回:仅返回插入文档的键*/
FOR i IN 1..100
    INSERT {
        value: i
    }IN test
RETURN NEW._key

五、高级操作

1.FOR 与 OPTION
/*子查询*/
FOR u IN users
  LET subquery = (FOR l IN locations RETURN l.location)
  RETURN { "user": u, "locations": subquery }
/*option*/
FOR … IN … OPTIONS { indexHint: "byName" }

indexHint/forceIndexHint

disableIndex:不进行索引查找或者扫描,进行完整的集合扫描

maxProjections/useCache/lookahead

2.RETURN

return会关闭当前范围并消除其中所有的局部变量

RETURN DISTINCT使结果唯一

3.SEARCH

关键字SEARCH启动语言构造来过滤视图,由底层索引加速。它保证将这些索引用于高效的执行计划。如果对视图使用关键字FILTER,则不会使用任何索引,并且过滤是作为后处理步骤执行的。

FOR doc IN viewName
  SEARCH expression
  OPTIONS { … }
  ...

SEARCH是FOR语句的一部分,不能随意用,也不能嵌套在FOR语句中

4.SORT, LIMIT, LET
FOR u IN users
  SORT u.lastName, u.firstName, u.id DESC
  RETURN u
/*DESC降序ASC升序*/

FOR u IN users
  SORT u.firstName, u.lastName, u.id DESC
  LIMIT 2, 5
  RETURN u
/*LIMIT跳过前两个数据,开始返回接下来的5个数据*/

LET语句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 
  }
/*LET主要用于声明复杂的计算*/
5.COLLECT

COLLECT操作可用于按一个或多个组标准对数据进行分组。它还可用于检索所有不同的值、计算值出现的频率以及有效地计算统计属性。

/*简单的分组操作*/
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 
  }
/*代码注解:数组users先按国家分组,然后按城市分组,对于国家和城市的每个不同组合,将返回用户。*/

/*通过COLLECT以及重写操作,丢弃不要的变量*/
COLLECT country = u.country, city = u.city INTO groups = u.name

WITH COUNT INTO不如使用AGGREGATE,聚合函数,他必须跟在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 
  }
6.WINDOW

WINDOW操作可用于相邻文档的聚合,或者换句话说,前行后行聚合。

基于行的聚合,基于范围的聚合,基于持续时间的聚合(https://www.arangodb.com/docs/stable/aql/operations-window.html)

7.REMOVE, UPDATE, REPLACE, INSERT

UPDATE/REPLACE <document> IN <collection>

使用这种语法时,document对象必须带有文档键的属性_key

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

UPDATE/REPLACE <keyExpression> WITH <document> IN <collection>

由keyExpression来决定

UPDATE "my_key" WITH { name: "Jon" } IN users
8.UPSERT

UPSERT关键字可用于检查某些文档是否存在,如果存在则更新/替换它们,或者如果它们不存在则创建它们。

UPSERT searchExpression INSERT insertExpression UPDATE updateExpression IN collection

UPSERT { name: 'superuser' }   /*如果已经有,则执行UPDATE*/
INSERT { name: 'superuser', logins: 1, dateCreated: DATE_NOW() }   /*如果没有,则执行INSERT*/
UPDATE { logins: OLD.logins + 1 } IN users

这段代码用来在 users 集合中插入或更新一条记录。如果集合中已经存在一个名为 superuser 的记录,那么它的 logins 字段将会增加 1。如果不存在,那么将会插入一条新的记录,其中 name 字段为 superuserlogins 字段为 1,而 dateCreated 字段则为当前日期。