这篇文章主要是总结云开发中踩的坑,优化了往期项目中的一些做法。
顺便总结一下私信/邮件中比较高频的问题。
一个帖子,获取的时候分为两个部分,如下图所示:
原方法:第一部分是帖子本身的信息,第二部分是关于作者的信息。之前在往期的项目中,采取的是拼接的方法,即获取帖子item[],再获取作者useritem[],这样相当于获取两回而且还多了一个集合。
/*原方法截取*/
that.data.UsernameArry = [];
that.data.UserHeadurlArry=[];
for (let i = 0; i < this.data.DataPostArry.length;i++){
let openId = this.data.DataPostArry[i]._openid;
for(let j=0;j<res.data.length;j++){
if(openId == res.data[j]._openid){
that.data.UsernameArry.push(res.data[j].Username);
that.data.UserHeadurlArry.push(res.data[j].User_head_url);
}
that.setData({
UsernameArry: that.data.UsernameArry,
UserHeadurlArry: that.data.UserHeadurlArry
});
优化方法:采用云开发Aggregate进行聚合操作1,联表查询,做外连接,这样可以直接在get的阶段把作者和帖子的内容取到一个集合当中。
return db.collection('A表').aggregate()
.lookup({
from: 'B表',
localField: 'A表关联的字段',
foreignField: 'B表关联的字段',
as: '匹配出的记录列表要存放的字段名',
}).match({
'字段匹配': '字段匹配',
}).end()
往期点赞采取的方式是页面中点赞,采用的是利用数组赋值0/1,点赞的时候判断数组,点赞之后不能取消。 需要优化的原因在于方法结构太过于死板,导致整段代码十分冗余而且不好操作。
/*原方法的节选*/
for (var i = 0; i < res.data.length; i++) {
UserUpId[i] = res.data[i].Up_Post_id//点赞列表赋值
}
for (var i = 0; i < res.data.length; i++) {
UserIdArry[i] = res.data[i]._id //所有的用户列表_id
if (UserUpId.indexOf(UserIdArry[i]) == -1) {
var item = 'UpArray[' + i + ']'
that.setData({
[item]: 0
})
}
else {
var item = 'UpArray[' + i + ']'
that.setData({
[item]: 1
})
}
优化方法:创建一个新的数据表,专门用来存储关于帖子的Status(状态),点赞状态的切换直接操作这个数据表即可。(点赞转移到评论区-内-即进入帖子后再进行操作 。收藏的功能实现亦是一样的操作)。
原方法:导航栏做的时候,采取的方法是一次获取,然后隐藏元素的方式,通过点击判断切换hide/show状态。这样写的页面太繁琐了,就单个页面显得很杂,其实有些地方可以复用,就不需要再多写一遍。
优化的方法:同类型的页面进行复用,获取数据的格式尽量相同。有些地方在前端可以利用block去操作。
这里用到的是Aggregate聚合操作1中的.match和.lookup。利用match匹配相关条件,lookup获取帖子与作者的集合(即优化的获取内容方式)。
return db.collection('帖子表').aggregate()
.lookup({
from: '用户表',
localField: '帖子表匹配的内容',
foreignField: '用户表匹配的内容',
as: '返回数组名称',
}).match(//正则匹配,满足两个条件其一即可
_.or([{
'条件一': db.RegExp({
regexp: '.*' + '搜索的内容',
options: 'i',
})
},
{
'条件二': db.RegExp({
regexp: '.*' + '搜索的内容',
options: 'i',
})
}
])).end()
小程序中有自带的获取当前位置函数2–wx.getLocation
用户开放权限后,会获取到经纬度,不过暂时没有提供解析位置的服务,所以一般会采用第三方的工具进行解析。
这里常用的就有腾讯/百度/高德,它们的官网都有比较完备的开发手册,专门用于微信小程序的SDK。
这里主要功能是实现地址的解析/关键词输入提示/路线规划。
热词检索的效果:
这里我用的是百度的sdk–百度开发文档,定位/描点/点击标志颜色,处理函数格式大同小异。
//地址解析
Map.regeocoding({
fail: fail,
success: success,
//location: latitude+ ',' + longitude,//经纬
iconPath: '/icons/marked.png',
iconTapPath: '/icons/markedTap.png'
});
//热词联想
Map.suggestion({
query: '传入热词',
region: '城市地区',
city_limit: 'true/false', //城市范围限制
fail: fail,
success: success
});
//POI检索
Map.search({
"query": "生活/酒店/交通/美食",
fail: fail,
success: success,
iconPath: '/icons/marked.png',
iconTapPath: '/icons/markedTap.png'
});
注意要做好权限的获取:
"permission": {
"scope.userLocation": {
"desc": "你的定位信息只用于天气/周边服务"
}
},
利用wx.request3发起 HTTPS 请求,每个不同的功能有不同的接口地址,有些需要设置请求头什么的。
按照提供api接口的制定的规则,发起请求,获取返回数据,然后再进行处理。
这个功能跟地图SDK接入的方法差不多,找到较稳定的短信验证码接口平台,按照规范接入平台SDK。
这里首先引入官方文档中的解释:
小程序端与云函数端的表现会有如下差异:
小程序端:如果没有指定 limit,则默认且最多取 20 条记录。
云函数端:如果没有指定 limit,则默认且最多取 100 条记录。
有比较多的朋友已经发现,前面项目获取的数量有瓶颈,所以可以采取.skip()和 .limit()关键字,在云函数中获取的时候计算数量,超过的时候进行拼接再返回。
Collection.get()官方实例
在授权页面加入判断,每个用户有个独立的openid。第一次用户进入的时候,用户的记录已经记录在你的用户表中,取消授权它的记录仍然会在库内。
各有千秋,满足业务需求就好。如果只是做个小工具什么的,其实原生也够用的,也不一定说非要上什么框架合适。主要是多思考别人实现的方式,关注功能背后逻辑是怎么实现的。如果让自己去实现,能不能实现/为什么利用这种方式实现。
一定要记住,小程序端数据库操作权限限制>>云函数。
首先,检查云数据库的权限是否已经开放。
如果在小程序端操作数据库,发现没报错/又没效果(一般是更新),先放在模版中跑一跑。
能成功的,说明是在小程序端操作被限制,只能在云函数端进行处理。
更新数组,有数组中有数组再有对象的更新
//数组.数组.下标.对应的字段
return db.collection(A表).doc(id).update({
data: {
[`数组.数组里面数组.${位置}.更新的字段`]: '内容' },
})
有数组中更新数组的
//数组.下标.对应的字段
return db.collection(A表).doc(id).update({
data: {
[`数组.${位置}.更新的字段`]: '内容' },
})
还有更新纯数组[“AA”,“BB”,“CC”]
return db.collection(A表).doc(id).update({
data: {
[`数组名字.${位置}`]: '内容'
},
})
基本上,如果理解其中一个就能实现以上。
一开始我利用_openid做查询条件,用空的作为条件,在小程序端能给我返回我自己数据,可是我在云模版下查询并没有结果。
(只是单独openid条件进行匹配)
后面才知道,在小程序端where会自带openid为小程序使用者openid的条件。
也就是说,即使你指定是其他人的openid,在利用openid条件进行匹配的时候,在小程序端也只会匹配返回使用者的openid的信息。
云函数方面就没有这条件,所以后来改用在云函数中,用openid条件进行匹配再做返回。
微信小程序正不断的完善与发展中,越来越多的功能也在陆续更新。
后面我也会陆续发布新的内容,希望我的文章能给大家带来帮助。
文笔有限,若有遗漏错误之处,欢迎讨论指出~
数据库集合的聚合操作–聚合操作 ↩︎ ↩︎
获取经纬度 ↩︎
发起的wx.request请求–request请求 ↩︎