云函数简介

云函数是一段部署在服务端的代码片段,通过云函数可以解决很多复杂的业务逻辑,无需将大量的数据发送到客户端做计算处理,大大减轻了客户端业务开发的复杂度。
另外,更新云函数代码片段,客户端无需更新,便满足业务改动的需求,这样云函数便有更多的灵活性和自主性。

编程语言

目前Bmob云函数支持Node.js和Java两种编程语言。

云函数执行方式

创建好的云函数支持三种执行方式:

  • 定时任务
    在服务端创建并设置定时任务规则后定时执行指定的云函数
  • RESTful Api调用
    通过Restful api接口调用指定云函数返回执行结果
  • SDK调用
    通过Bmob数据服务提供的相关平台SDK中提供的方法调用指定云函数

数据准备

假设现在有一张用户表_User存储注册的用户信息,主要的基本字段如下:
| 字段 | 数据类型 | 描述 |
| ——– | :—–: | —-: |
| username | String | 用户名 |
| password | String | 密码 |
| type | Integer | 用户类型(1普通用户、2高级用户) |

需求

老板要求统计每天不同类型的用户注册量

创建云函数

在Bmob控制台创建countRegister的云函数

创建后台的countRegister云函数的默认内容如下:

在onRequest方法体中我们将实现注册量统计的逻辑,这里需要注意几点:

  • 方法名、入参及返回类型不允许任何修改
  • 代码中不能包含以下关键字
    Class
    File
    System
  • 需要获取当前毫秒时,可用 getTime() 、new java.util.Date().getTime() 替代 System.currentTimeMillis()
  • 如果确实需要用到被禁止使用的关键字,例如查询”File”表,可用”F”+”ile”的形式拼接
  • 不可包含/**/注释,如需注释,请用 //
  • 仅可写一个Java的方法,不能写多个方法、类变量、静态变量等
  • 云函数执行完毕后,必须用response.send方法返回响应数据,否则会被当做超时,多次超时可能会被暂停使用

了解了以上规则后我们就来开始编写统计数据的代码:

1
2
3
4
5
6
7
8
9
10
11
// 按type字段进行分组统计
Querier qt = new Querier("_User")
.limit(1000)
.groupby("type")
.groupcount(true);
// 条件 = 创建时间在12小时内
qt.addWhereGreaterThanOrEqualTo("createdAt", new BmobDate(getTime() - 12 * 60 * 60 * 1000));
// 使用oData对象的find方法进行数据的查询统计
HttpResponse httpResponse = modules.oData.find(qt);
// 将查询统计得到的数据通过httpResponse返回给调用云函数的请求方
response.send(httpResponse.jsonData);

调用云函数

云函数的调用支持以下几种方式:
|调用方式 |所需信息 |优点
| ——– | :—– | :—- |
|SDK |AppId |交互自带加密,接入快速
|RestApi |AppId、RestKey |所有平台适用,通用性强
|Http请求 |Secret Key |所有平台适用,可用浏览器打开

这里使用Http请求的方式调用countRegister云函数进行测试,在浏览器中请求如下地址:https://javacloud.bmob.cn/****/countRegister,星号请替换为您Bmob应用的SectetKey
这个时候假设当前_User表中存储的数据如下:
| username | password | type |
| ——– | :—– | :—- |
| zhangsan | 123456 | 1 |
| lisi | 123456 | 2 |
| wangwo | 123456 | 1 |
执行此云函数返回的Json数据将是如下结果:

1
{"results":[{"_count":1,"type":2},{"_count":2,"type":1}]}

results中的结果分别是普通用户(type=1)和高级用户(type=2)的注册总数。
到此已经实现了基本的统计操作,主要是在云函数中使用了数据服务的查询功能来进行统计查询。而实际的业务中可能需要我们将统计的结果存储到相关的数据表中方便以后做报表展示,所以我们接下来继续完善一下这个countRegister云函数,将统计的结果存储到一张表中。

保存统计数据

新建一个Statistics表,存储统计后的结果,结构如下:
| 字段 | 数据类型 | 描述 |
| ——– | :—–: | —-: |
| generalUserCount | Integer | 普通用户注册数量 |
| advancedUserCount | Integer | 高级用户注册数量 |

加入存储统计数据的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 按type字段进行分组统计
Querier qt = new Querier("_User")
.limit(1000)
.groupby("type")
.groupcount(true);
// 条件 = 创建时间在12小时内
qt.addWhereGreaterThanOrEqualTo("createdAt", new BmobDate(getTime() - 12 * 60 * 60 * 1000));
// 使用oData对象的find方法进行数据的查询统计
HttpResponse httpResponse = modules.oData.find(qt);
// 将查询统计得到的数据通过httpResponse返回给调用云函数的请求方
//response.send(httpResponse.jsonData);

JSONArray results = httpResponse.jsonData.getJSONArray("results");
if (results == null) {
response.send(httpResponse.data); // 请求有错误,直接返回全部内容
} else {
JSONObject statisticsData = new JSONObject();
for(int i = 0; i < results.size(); i++){
JSONObject obj = results.getJSONObject(i);
int type = obj.getInteger("type");
int count = obj.getInteger("_count");
if(type == 1){
// 普通用户总数
statisticsData.put("generalUserCount", count);
}else if(type == 2){
// 高级用户总数
statisticsData.put("advancedUserCount", count);
}
}
// 保存数据并返回执行结果
response.send(modules.oData.insert("Statistics", statisticsData).stringData);
}

保存好代码后再次调用该云函数,返回结果如下:

1
{"createdAt": "2017-12-27 16:04:35","objectId": "8401a6d2d9"}

表示插入Statistics表数据成功后返回的数据objectId和创建时间,Bmob控制台数据浏览Statistics表,已经存在统计后的数据了:

定时任务

上面的云函数已经基本完成了用户注册数的统计以及保存统计数据的工作,但是当我们需要统计的时候还需要手动的调用countRegister云函数才行。实际上我们可以创建一个定时任务在固定时间来执行这个统计操作。在云函数的编写页面选择定时任务,设置执行规则后保存即可,具体设置如下:

上面的规则是每天的23点执行该云函数,定时任务的执行规则可以参考定时任务文档说明。

总结

本文以一个统计用户注册数量的简单实例来讲解了Bmob云函数的使用,主要在云函数中使用到了数据服务的查询数据和插入数据来实现,并在最后介绍了定时任务+云函数的搭配使用。很多时候,单纯的前端代码是不能完成全部事情的,一些重要和复杂的业务逻辑还是希望能够在服务端中执行。比如:对比较大量的比赛数据进行排序、对某些数据进行分析和处理、获取用户的IP信息等等。


  • 本博客所有文章除特别声明外,均采用CC-BY-NC-SA 4.0 许可协议进行许可
  • 欢迎转载,但请注明来自稻草人,并保持转载后文章内容的完整,本人保留所有版权相关权利。

本文链接:http://www.googol.tech/2017/12/27/使用BmobJava云函数统计数据/