获取当前数据库歌单列表的云函数
作用 定时的从获取数据信息到数据库 并切解决 分批处理,去重插入
事先准备的API来发送请求获取数据
const URL = 'http://musicapi.xiecheng.live/personalized'
把对应的请求插入到数据库的集合当中,这里要额外注意async 和 await
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
//云数据库的初始化
const db = cloud.database()
const rp = require('request-promise')
const URL = 'http://musicapi.xiecheng.live/personalized'
// 云函数入口函数
exports.main = async(event, context) => {
const playlist = await rp(URL).then((res) => {
return JSON.parse(res).result
})
// console.log(playlist)
for(let i =0, len = playlist.length; i<len ; i++){
await db.collection("playlist").add({
data:{
...playlist[i],
createTime:db.serverDate()
}
}).then((res) => {
console.log("插入成功")
}).catch((err) => {
console.error("插入失败")
})
}
}
问题1: 如果当前歌已存在数据库 如何避免去重?
1 先读取数据库playlist中的信息存放在list
2 获取服务器的数据存在playlist
3通过循环比较 将新的数据存放在newData[]
4再插入数据库
const list = db.collection("playlist").get()
// 云函数入口函数
exports.main = async(event, context) => {
//取到数据库 playlist中所有数据(放在list中data中),注意:该操作是异步操作 要加await
const list = await playlistCollection.get()
//等待 rp获取资源 并 将结果由字符串转化为对象
const playlist = await rp(URL).then((res) => {
return JSON.parse(res).result
})
//此时 list中为获取的 数据库 的资源,
//playlist为 从服务器获取的资源
//插入数据库之前 要进行去重复
const newData = []//用来放去重复之后要插入的数据
for(let i=0,len1 = playlist.length; i<len1;i++){
let flag =true
for(j=0,len2 = list.data.length; j<len2; j++){
if(playlist[i].id === list.data[j].id){
flag =false
break
}
//若获取服务器中的第【i】条数据与 获取数据库并存放在list中的数据都不重复
//则将数据写入newData[] 用来后期插入数据库
if(flag){
newData.push(playlist)
}
}
}
// 循环newData[]中的数据 并 加入数据库
for(let i =0, len = newData.length; i<len ; i++){
await playlistCollection.add({
data:{
...newData[i],
createTime:db.serverDate()
}
}).then((res) => {
console.log("插入成功")
问题2:对云函数来说 取数据是有限制的 获取数据最多获取100条 , 从小程序端获取数据最多获取20条,如何突破限制?
歌单的信息会不断的增多,所以100条是不满足需求的
1获取总的数据条数 这里返回的是一个对象(是异步操作 + await)
const countResult = await playlistCollection.count()
2通过当前 对象.total得到number型的数字,这时获得了总的条数
const total = countResult.total
3计算需要取几次 = 总的条数/每次取的条数 注意要向上取整
定义一个常量 来计算 得到次数 batchTimes
const MAX_LIMIT = 100
const batchTimes = Math.ceil(total / MAX_LIMIT)
4这里注意 因为要分多次加入 所以要等所有的获取处理完 及要用到Promise
const tasks = []
for (let i = 0; i < batchTimes; i++) {
let promise = playlistCollection.skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
tasks.push(promise)
}
let list = {
data: []
}
if (tasks.length > 0) {//如果需要分多次取
list = (await Promise.all(tasks)).reduce((acc, cur) => {//当所有完成
return {
data: acc.data.concat(cur.data)//拼接上当前数据
}
})
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
//云数据库的初始化,生成一个DB对象
const db = cloud.database()
const rp = require('request-promise')
const URL = 'http://musicapi.xiecheng.live/personalized'
//因为要多次获取数据库,所以再获取数据用playlistCollection就可以
const playlistCollection = db.collection("playlist")
const MAX_LIMIT = 100
/////////////////////////////////
///////////云函数入口函数//////////
//////////////////////////////////
exports.main = async (event, context) => {
// const list = await playlistCollection.get()
const countResult = await playlistCollection.count()
const total = countResult.total
const batchTimes = Math.ceil(total / MAX_LIMIT)
const tasks = []
for (let i = 0; i < batchTimes; i++) {
let promise = playlistCollection.skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
tasks.push(promise)
}
let list = {
data: []
}
if (tasks.length > 0) {
list = (await Promise.all(tasks)).reduce((acc, cur) => {
return {
data: acc.data.concat(cur.data)
}
})
}
const playlist = await rp(URL).then((res) => {
return JSON.parse(res).result
})
const newData = []
for (let i = 0, len1 = playlist.length; i < len1; i++) {
let flag = true
for (let j = 0, len2 = list.data.length; j < len2; j++) {
if (playlist[i].id === list.data[j].id) {
flag = false
break
}
}
if (flag) {
newData.push(playlist[i])
}
}
for (let i = 0, len = newData.length; i < len; i++) {
await playlistCollection.add({
data: {
...newData[i],
createTime: db.serverDate(),
}
}).then((res) => {
console.log('插入成功')
}).catch((err) => {
console.error('插入失败')
})
}
return newData.length
}
问题三:每次都要手动的添加数据吗!?
解决:定时的触发函数 用到云函数的触发器
参考:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/triggers.html
1 新建个一json函数 (注意json函数内不可写注释)
2 设置每天的 3 9 15 21点定时更细
3 上传触发器