ArangoDB系列——01 Getting Started

859 阅读7分钟

由于网上关于ArangoDB的中文资料较少,系列文章的内容均来自于官网和其他资料

本文带领用户初步熟悉如何在本机启动ArangoDB服务程序,使用web界面与之交互,并简单看几个数据的增删改查例子。

安装

Download ArangoDB database: Enterprise and Community

打开下载链接,如下图所示,我们点击下载社区版:

图1.1:从download页面下载社区版,oasis是官方提供的云服务,与企业版一样,均收费

官方提供了各种操作系统的下载安装方式,请根据自身情况选择。

安装后,默认包含一个数据库,名叫 _system,一个默认用户, 名叫root

设置密码

安装官方说明,如果是在Debian和Windows安装,则安装过程会提示输入密码, Red-Hat会设置一个随机的密码,其他系统上安装,需要自行执行如下命令,会要求为root用户设置一个密码

shell> arango-secure-installation  # 

本文使用了Mac OS下载dmg的方式安装,未对root用户设置密码,可认为密码为空

登录认证

上一节提到,在安装期间会创建一个默认用户 root,该用户可以访问所有数据库。 在实际开发中,应该为你的应用创建一个单独的数据库,并创建相应有权限的用户(详见,管理用户

如下是一个示例,创建一个样例数据库叫做 example, 一个用户叫做 root@example

arangosh> db._createDatabase("example");
arangosh> var users = require("@arangodb/users");
arangosh> users.save("root@example", "password");
arangosh> users.grantDatabase("root@example", "example");

随后可以使用用户名root@example来连接到新建的数据库
shell> arangosh --server.username "root@example" --server.database example 


Web界面

Server本身 (也叫arangod) 使用 HTTP / REST,也可以使用 Web 界面(叫做Aardvark)或者arangosh命令行的方式来交互。

本节介绍Web界面,当安装完成之后,Server会自动启动,此时可以用http://localhost:8529打开web界面,之前提到默认的用户名是root,如果没设置过密码,则为空

                                               图3.1:web界面,输入用户名密码

随后,会要求选择连接哪个数据库,安装后默认有一个_system,此处选择_system继续。

                                                             图3.2 选择数据库

登录后,可以点击左侧的dashboard仪表盘,查看server的相关信息:

图3.3:dashboard界面

Databases, Collections 和 Documents

本节介绍几个术语。使用传统的RDBMS类比,会发现ArangoDB与MongoDB中的术语一样。在Arangdb中,用户无需提前定义documents中有哪些属性

 

表4.1:RDBMS与Arangodb术语对比

在web界面中,左侧的菜单栏里选择 COLLECTIONS, 随后点击空白处的 Add Collection,添加一个 名为 users 的collection,其他选项不用修改(保持users是一个 document collection)并保存,随后会看到刚建立的名为 users的项弹出。

图4.1:添加第一个Colletion,名为users

此时还没有创建任何的documents,可以点击右上角 白十字绿色圆圈创建第一个document。 会弹出一个窗口,要求填写 _key,如果不填,系统会自动生成一个 _key,这里注意,_key一旦创建就是不可变的,_key总是string类型,比如本例中 "4904", 相应地,document _id为 "users/4904" (你本地生成的_key应该跟本例不一样)

图4.2:创建第一个document,_key由系统自动生成

创建完后,从新点击左侧菜单栏COLLECTIONS,打开名为users的collection,会看到我们刚建立的document。

图4.3:查看新建立的document

AQL

ArangoDB所用的查询语言叫AQL,本节我们使用AQL做一些基本增删改查操作。

从左侧菜单栏中,选择 QUERIES,在右侧的编辑窗口中,输入如下AQL语句(把document _id换成你本地的_id), 然后点击右下角的 Execute执行, 查询结果会直接出现在编辑窗口下方。

RETURN DOCUMENT("users/4904") # 此处使用了DOCUMENT函数,返回_id为users/4904的document

图4.4: 执行AQL语句, 查询新建立的document

刚才的语句执行了查询操作,现在我们执行一条插入语句,执行后的结果为 [] (空的array),因为我们没有使用关键字RETURN来明确指明要返回什么

INSERT { name: "Katie Foster", age: 27 } INTO users # 注意INTO后面的collection名称无需加引号

上述语句在users中新建立了一个document,如果想在执行插入后,确认刚插入的document,可以这样写AQL:

INSERT { name: "James Hendrix", age: 69 } INTO usersRETURN NEW

结果如图4.5所示:

图4.5:插入并返回所插入的数据

至此,我们一共建立了3个users, 如果想查询出全部3个users,可以执行如下语句:

RETURN DOCUMENT( ["users/4904", "users/5637", "users/5805"] ) # DOCUMENT函数中传入一个数组[], 

很显然此种方式很不方便,还有更好的查询方式:

FOR user IN users   
    RETURN user  # 此处使用了变量名user,实际上可以任意命名

执行结果有两种显示方式 Table/JSON, 如图4.6所示,可以来回切换:

图4.6: 查询结果显示方式

你可能会发现,返回结果的顺序不一定跟插入的顺序一致。返回结果的顺序确实无任何保证,除非你明确指定了排序,例如:

FOR user IN users
  SORT user._key
  RETURN user   # 注意, user._key是string类型,所以 10074按照字典序排序后,会在9883之前

如果按照年龄排序(年龄是int整形):

FOR user IN users   
    SORT user.age DESC   # 默认不填为ASC升序
    RETURN user

还可以加入过滤条件:

FOR user IN users   
    FILTER user.age > 30   # Katie年龄不符合,最终返回两条结果
    SORT user.age   
    RETURN user

下面是如何修改某个user的属性,此处我们把Katie的年龄也修改为大于30, 使用UPDATE可以部分修改某个document, 本例中,只更新了age属性,其他属性都原封不动。还有一个REPLACE关键字,会删掉除_key和_id的所有属性,只留下用户指定的新属性

UPDATE "5637" WITH { age: 40 } IN users  # katie的_key为 5637
RETURN NEW

修改后,我们再次用年龄过滤,这一次只返回满足过滤条件的人名:

FOR user IN users
    FILTER user.age > 30
    SORT user.age
    RETURN user.name
    
# 返回结果:
[
  "John Smith",
  "Katie Foster",
  "James Hendrix"
]


###########################################
# 还可以修改返回的列名
FOR user IN users
    FILTER user.age > 30
    SORT user.age
    RETURN {userName: user.name, age: user.age}
    
# 返回结果:
[
  {
    "userName": "John Smith",
    "age": 32
  },
  {
    "userName": "Katie Foster",
    "age": 40
  },
  {
    "userName": "James Hendrix",
    "age": 69
  }
]

# 还可以对不同的返回字段进行拼接
FOR user IN users
    FILTER user.age > 30
    SORT user.age
    RETURN CONCAT(user.name, "'s age is ", user.age) # CONCAT返回string

# 返回结果:
[
  "John Smith's age is 32",
  "Katie Foster's age is 40",
  "James Hendrix's age is 69"
]

再来看一个复杂的例子,我们使用双层FOR循环,将任意两个用户的组合全部找到(3个users,一共是3*3=9种可能,排除掉自己跟自己的组合,还剩6种)

FOR user1 IN users
  FOR user2 IN users
    FILTER user1 != user2
    RETURN {user1name: user1.name, user2name:user2.name}

# 返回结果:
[  {    "user1name": "James Hendrix",    "user2name": "John Smith"  },  {    "user1name": "Katie Foster",    "user2name": "John Smith"  },  {    "user1name": "John Smith",    "user2name": "James Hendrix"  },  {    "user1name": "Katie Foster",    "user2name": "James Hendrix"  },  {    "user1name": "John Smith",    "user2name": "Katie Foster"  },  {    "user1name": "James Hendrix",    "user2name": "Katie Foster"  }]


# RETURN语句不一样,最终返回的格式不一样
FOR user1 IN users
  FOR user2 IN users
    FILTER user1 != user2
    RETURN [user1.name, user2.name]
    
# 返回结果:

[  [    "James Hendrix",    "John Smith"  ],
  [    "Katie Foster",    "John Smith"  ],
  [    "John Smith",    "James Hendrix"  ],
  [    "Katie Foster",    "James Hendrix"  ],
  [    "John Smith",    "Katie Foster"  ],
  [    "James Hendrix",    "Katie Foster"  ]
]

还可以在循环中使用LET定义临时变量,以便在FILTER中使用该临时变量:

FOR user1 IN users
  FOR user2 IN users
    FILTER user1 != user2
    LET sumOfAges = user1.age + user2.age # 定义sumOfAges临时变量
    FILTER sumOfAges < 100 # 第一次使用sumOfAges
    RETURN {
        pair: [user1.name, user2.name],
        sumOfAges: sumOfAges # 第二次使用sumOfAges
                             # sumOfAges: sumOfAges 冒号两边都一样时,可以只写一遍 sumOfAges
    }
    
    #返回结果
    [
  {
    "pair": [
      "Katie Foster",
      "John Smith"
    ],
    "sumOfAges": 72
  },
  {
    "pair": [
      "John Smith",
      "Katie Foster"
    ],
    "sumOfAges": 72
  }
]

最后看看删除语句:

REMOVE "4904" IN users

# 使用FOR循环删除掉所有大于等于30岁的用户, 至此users成为空,所有用户都被删除掉了
FOR user IN users     
    FILTER user.age >= 30     
    REMOVE user IN users

来自SQL背景

如果你是来自RDMBS的SQL背景,那么AQL主要的区别之一是循环,这使得AQL更像一种编程语言,这很适合schema-less的模型,使AQL更强大同时还容易阅读和编写。

AQL中的RETURN语句,会为每个将返回的document返回一项,可以返回整个document,也可以返回该document的一部分,以下例子中,我们假定 oneDocument 是一个document,不同的RETURN语句,返回结果不同:

RETURN oneDocument

[  {    "_id": "myusers/3456789",    "_key": "3456789",    "_rev": "14253647",    "firstName": "John",    "lastName": "Doe",    "address": {      "city": "Gotham",      "street": "Road To Nowhere 1"    },    "hobbies": [      {        "name": "swimming",        "howFavorite": 10      },      {        "name": "biking",        "howFavorite": 6      },      {        "name": "programming",        "howFavorite": 4      }    ]
  }
]

# 只返回hobbies
RETURN oneDocument.hobbies

[  [    {      "name": "swimming",      "howFavorite": 10    },    {      "name": "biking",      "howFavorite": 6    },    {      "name": "programming",      "howFavorite": 4    }  ]
]



# 只返回第一个hobby的名字
RETURN oneDocument.hobbies[0].name

["swimming"]


#将所有hobbies的名字作为字符串返回
RETURN { hobbies: oneDocument.hobbies[*].name }

[  {    "hobbies": ["swimming","biking","programming"]
  }
]

参考

  1. Getting Started | Manual | ArangoDB Documentation