# 数据库

# 基础概念

# Collection

集合是一系列的文档集,通过 Db.Collection(name) 可以获取指定集合的引用,在集合上可以进行以下操作

类型 接口 说明
Add / AddAsync 新增文档(触发请求)
计数 Count / CountAsync 获取复合条件的文档条数(触发请求)
Get / GetAsync 获取集合中的文档,如果有使用 Where 语句定义查询条件,则会返回匹配结果集(触发请求)
引用 Doc 获取对该集合中指定 id 的文档的引用
查询条件 Where 通过指定条件筛选出匹配的文档,可搭配查询指令(eq, Gt, in, ...)使用
Skip 跳过指定数量的文档,常用于分页,传入 offset
OrderBy 排序方式
Limit 返回的结果集(文档数量)的限制,有默认值和上限值
Field 指定需要返回的字段

查询及更新指令用于在 Where 中指定字段需满足的条件,指令可通过 db.command 对象取得。

# Record / Document

文档是数据库集合中的一个存储单元,在云开发里是一个json对象。通过 Db.Collection(collectionName).Doc(docId) 可以获取指定集合上指定 id 的文档的引用,在文档上可以进行以下操作

类型 接口 说明
Set / SetAsync 覆写文档(触发请求)
Update / UpdateAsync 局部更新文档(触发请求)
Remove / RemoveAsync 删除文档(触发请求)
Get / GetAsync 获取文档(触发请求)

# Query Command

查询指令,应用于构建查询条件。以下指令皆挂载在 Db.Command

类型 接口 说明
比较运算 Eq 字段 ==
Neq 字段 !=
Gt 字段 >
Gte 字段 >=
Lt 字段 <
Lte 字段 <=
In 字段值在数组里
Nin 字段值不在数组里
逻辑运算 And 表示需同时满足指定的所有条件
Or 表示需同时满足指定条件中的至少一个

# Update Command

更新指令,应用于构建更新操作。以下指令皆挂载在 Db.Command

类型 接口 说明
更新指令 Set 设定字段等于指定值
Inc 指示字段自增某个值
Mul 指示字段自乘某个值
Remove 删除某个字段
Push 向数组尾部追加元素,支持传入单个元素或数组
Pop 删除数组尾部元素
Shift 删除数组头部元素。使用同pop
Unshift 向数组头部添加元素,支持传入单个元素或数组。使用同push

# 获取数据库实例

说明:传入 CloudBaseCore 实例,返回数据库的实例

using CloudBase;

CloudBaseApp app = CloudBaseApp.Init("your-env-id", 3000);
Database db = app.Db;

# 获取集合的引用

说明:接受一个 name 参数,指定需引用的集合名称

using CloudBase;

CloudBaseApp app = CloudBaseApp.Init("your-env-id", 3000);
Database db = app.Db;
Collection collection = db.Collection("user");

# 查询指令

# Eq

表示字段等于某个值。Eq 指令接受一个字面量 (literal),可以是 int, float, bool, string, object

比如筛选出所有自己发表的文章,除了用传对象的方式:

string myOpenID = "xxx";
db.Collection("articles").Where(new {
  _openid = myOpenID
});

还可以用指令:

Command command = db.Command;
string myOpenID = "xxx";
db.Collection("articles").Where(new {
  _openid = command.Eq(myOpenID)
});

# Neq

字段不等于。Neq 指令接受一个字面量 (literal),可以是 int, float, bool, string, object

如筛选出品牌不为 X 的计算机:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    brand = command.Neq("X")
  }
});

# Gt

字段大于指定值。

如筛选出价格大于 2000 的计算机:

Command command = db.command;
db.Collection("goods").Where(new {
  category = "computer",
  price = command.Gt(2000)
});

# Gte

字段大于或等于指定值。

# Lt

字段小于指定值。

# Lte

字段小于或等于指定值。

# In

字段值在给定的数组中。

筛选出内存为 8g 或 16g 的计算机商品:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    memory = command.In( new[] {8, 16})
  }
});

# Nin

字段值不在给定的数组中。

筛选出内存不是 8g 或 16g 的计算机商品:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    memory = command.Nin( new[] {8, 16})
  }
});

# And

表示需同时满足指定的两个或以上的条件。

如筛选出内存大于 4g 小于 32g 的计算机商品:

流式写法:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    memory = command.Gt(4).And(command.Lt(32)))
  }
});

前置写法:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    memory = command.And(new [] { command.Gt(4), command.Lt(32) })
  }
});

# Or

表示需满足所有指定条件中的至少一个。如筛选出价格小于 4000 或在 6000-8000 之间的计算机:

流式写法:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    price = command.Lt(4000).Or(
      command.Gt(6000).And(command.Lt(8000))
    )
  }
});

前置写法:

Command command = db.command;
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    price = command.Or(new [] {
      command.Lt(4000), 
      command.And( new [] {
        command.Gt(6000),
        command.Lt(8000)
      })
    })
  }
});

如果要跨字段 “或” 操作:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机)

Command command = db.command;
db.Collection("goods").Where(command.Or( new [
  new {
    type = {
      memory = command.Gt(8)
    }
  },
  new {
    type = new {
      cpu = 3.2
    }
  }
]));

# RegExp

根据正则表达式进行筛选

例如下面可以筛选出 version 字段开头是 "数字+s" 的文档,并且忽略大小写:

db.Collection("articles").Where( new {
  version = db.RegExp(
    "^\\ds",   // 正则表达式/^\ds/,转义后变成 "^\\ds"
    "i"        // options, i表示忽略大小写
  )
});

# 更新指令

# Set

描述:用于设定字段等于指定值。

示例代码:

// 以下方法只会更新 style.color 为 red,而不是将 style 更新为 { color: 'red' },即不影响 style 中的其他字段
db.Collection('todos').Doc('doc-id').Update( new {
  data = new {
    style = new {
      color = 'red'
    }
  }
});

// 以下方法更新 style 为 { color: 'red', size: 'large' }
Command command = db.Command
db.Collection('todos').Doc('doc-id').Update( new {
  data = new {
    style = command.set( new {
      color = 'red',
      size = 'large'
    })
  }
});

# Inc

描述:用于指示字段自增某个值,这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是:

  1. 原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况
  2. 减少一次网络请求:不需先读再写

之后的 Mul 指令同理。

示例代码:

Command command = db.command;
db.Collection("user").Where( new {
  _openid = "my-open-id"
}).Update( new {
  Count = new {
    favorites = command.Inc(1)
  }
});

# Mul

描述:用于指示字段自乘某个值。

# Remove

更新指令。用于表示删除某个字段。如某人删除了自己一条商品评价中的评分:

Command command = db.command;
db.Collection("comments").Doc("comment-id").Update( new {
  rating = command.Remove()
});

# Push

向数组尾部追加元素,支持传入单个元素或数组

Command command = db.command;
db.Collection("comments").Doc("comment-id").Update(new {
  // users = command.Push("aaa")
  users = command.Push(new [] {"aaa", "bbb"})
});

# Pop

删除数组尾部元素

Command command = db.command;
db.Collection("comments").Doc("comment-id").Update( new {
  users = command.Pop()
});

# Unshift

向数组头部添加元素,支持传入单个元素或数组。使用同push

# Shift

删除数组头部元素。使用同pop

# 构建查询条件

支持 Where()Limit()Skip()OrderBy()Get()Update()Field()Count() 等操作。

只有当调用Get()Update()时才会真正发送请求。

# Where

描述:设置过滤条件。Where 可接收对象作为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。

输入参数: 无

比如筛选出所有类型为计算机的、内存为 8g 的商品:

db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    memory = 8,
  }
});

如果要表达更复杂的查询,可使用高级查询指令,比如筛选出所有内存大于 8g 的计算机商品:

Command command = db.command // 取指令
db.Collection("goods").Where( new {
  category = "computer",
  type = new {
    memory = command.Gt(8), // 表示大于 8
  }
});

# Limit

描述:指定查询结果集数量上限

输入参数:

参数 类型 必填 说明
- int 限制展示的数值

使用示例

var res = collection.Limit(1).Get();

# Skip

描述:指定查询返回结果时从指定序列后的结果开始返回,常用于分页 输入参数:

参数 类型 必填 说明
- int 限制展示的数值

示例代码

var res = collection.Skip(4).Get();

# Field

描述:指定返回结果中文档需返回的字段

输入参数:

参数 类型 必填 说明
projection Dictionary<string, bool> 要过滤的字段,不返回传false,返回传true

示例代码

var res = collection.Field(new Dictionary<string, bool>{ {"age", true} }).Get();

备注:field方法接受一个必填对象用于指定需返回的字段,对象的各个 key 表示要返回或不要返回的字段,value 传入 true|false 表示要返回还是不要返回。

# OrderBy

描述:指定查询排序条件

输入参数:

参数 类型 必填 说明
field string 排序的字段
orderType string 排序的顺序,升序(asc) 或 降序(desc)

备注:方法接受一个必填字符串参数 fieldName 用于定义需要排序的字段,一个字符串参数 order 定义排序顺序。order 只能取 asc 或 desc。

同时也支持按多个字段排序,多次调用 OrderBy 即可,多字段排序时的顺序会按照 OrderBy 调用顺序先后对多个字段排序

示例代码

var res = collection.OrderBy("name", "asc").Get();

# Add

# 1. 接口描述

接口功能:插入一条文档

接口声明:public DbCreateResponse Add(object data)

备注:set方法也可以用来新增文档,请参看文档更新部分set方法

示例:

# 2. 输入参数

参数 类型 必填 说明
data object 新增文档的定义

# 3. 输出参数

# DbCreateResponse
字段 类型 说明
Code string 状态码,操作成功则不返回
Message string 错误描述
RequestId string 请求序列号,用于错误排查
Id string 文档id

# 4. 示例代码

var res = collection.Add(new {
  name = "Ben"
})

# Get

# 1. 接口描述

接口功能:获取数据库查询结果

接口声明:public DbQueryResponse Get(object data)

注:get()如不指定limit则默认取前100条数据,且最大取前100条数据。

# 2. 输入参数

# 3. 输出参数

# DbQueryResponse
字段 类型 说明
Code string 状态码,操作成功则不返回
Message string 错误描述
RequestId string 请求序列号,用于错误排查
Data JObject 匹配查询条件的文档
Limit int 限制数
Offset int 偏移量

# 4. 示例代码

var res = collection.Where( new {
  category = computer,
  type = new {
    memory = 8,
  }
}).Get();

# Count

# 1. 接口描述

接口功能:获取数据库查询结果的数量

接口声明:public DbQueryResponse Count()

# 2. 输入参数

# 3. 输出参数

# DbCountResponse
字段 类型 说明
Code string 状态码,操作成功则不返回
Message string 错误描述
RequestId string 请求序列号,用于错误排查
Total int 匹配查询条件的文档数量

# 4. 示例代码

var res = collection.Where( new {
  category = computer,
  type = new {
    memory = 8,
  }
}).Count();

# Remove

# 1. 接口描述

接口功能:删除一条文档

接口声明:public DbRemoveResponse> Remove()

# 2. 输入参数

# 3. 输出参数

# DbRemoveResponse
字段 类型 说明
Code string 状态码,操作成功则不返回
Message string 错误描述
RequestId string 请求序列号,用于错误排查
Deleted int 删除的文档数量

# 4. 示例代码

方式1:通过指定文档ID删除

var res = collection.Doc("xxx").Remove();

方式2:条件查找文档然后直接批量删除

// 删除字段a的值大于2的文档
var res = collection.Where( new {
  a = command.Gt(2)
}).Remove();

# Update / Set

# 1. 接口描述

接口功能:更新文档

接口声明:

public DbUpdateResponse Update(object data)

public DbUpdateResponse Set(object data)

备注:update和set都可以用来更新文档,区别是set方法在要更新的文档不存在时新增一个文档;而update方法什么也不会做,返回updated为0

# 2. 输入参数

字段 类型 必填 说明
data object 替换文档的定义

# 3. 输出参数

# DbUpdateResponse
字段 类型 说明
Code string 状态码,操作成功则不返回
Message string 错误描述
RequestId string 请求序列号,用于错误排查
Updated int 影响的文档数量
UpsertedId string 插入的文档的id

# 4. 示例代码

更新指定文档

//更新指定文档
var res = collection.Doc("doc-id").Update( new {
  name = "Hey"
});

更新文档,如果不存在则创建

//更新单个文档
var res = collection.Doc("doc-id").Set( new {
  name = "Hey"
});

//批量更新文档
collection.Where( new {
  name = command.Eq("hey")
}).Update( new {
  age = 18
});