【小程序】008 基于云函数获取数据并去重插入云数据库

举报
LongYorke 发表于 2021/02/04 16:09:10 2021/02/04
【摘要】 之前的歌单数据是在小程序里面写死的,不是从服务器上读取,无法实时更新。这一次我们要从服务器端取到相关数据,写到云数据库。通过云函数发送请求获取数据,并为之设置定时触发器,每天固定的时间到服务器上获取数据,这样就可以保持歌单数据的动态变化。同时可以比较旧数据,插入数据库里没有的歌单。1、新建Node.js云函数自命名2、request-promiserequest-promise在云函数上使用...
之前的歌单数据是在小程序里面写死的,不是从服务器上读取,无法实时更新。这一次我们要从服务器端取到相关数据,写到云数据库。
通过云函数发送请求获取数据,并为之设置定时触发器,每天固定的时间到服务器上获取数据,这样就可以保持歌单数据的动态变化。同时可以比较旧数据,插入数据库里没有的歌单。
1、新建Node.js云函数
自命名

在云函数上使用第三方库request-promise向服务器发送请求
1)打开终端(外部或内部皆可)



2)使用npm命令安装(注意使用npm要提前拥有nodejs环境,相关安装步骤可以参考【Hexo】笔记01:安装Hexo-云社区-华为云
使用以下命令检验是否安装相关内容
node -v
npm -v

3)安装request-promise
npm install --save request
npm install --save request-promise

由于request-promise依赖于request,所以两者安装顺序不能改变



如果提示当前npm并不是内部命令,尝试鼠标右键“以管理员身份访问”。
在package.json观察检验是否安装成功

4)定义常量,使用依赖

const rp = require('request-promise');

3、小程序调试器控制台显示的是前端代码,云函数属于后端代码,可以在云端测试中进行调试





找到云端测试


调用成功



也可以使用本地调试
使用须知
  • npm 依赖:若云函数中有使用到 npm 模块,需在云函数本地目录安装相应依赖才可正常使用云函数本地调试功能。


调用成功



4、创建数据库的歌单集合



调用云函数插入数据库需要对数据库进行相应的初始化
const db = cloud.database()
cloud是云函数自带的对象,database()方法。

5、处理获取的数据
我们获得的数据是JSON格式字符串,且只需要data中的list数组,可以转换成对象做进一步处理
  const playlist = await rp(URL).then((res) => {
    return JSON.parse(res).data.list
  })
  console.log(playlist)



6、数据插入云数据库
云数据库的插入只能单条插入,所以我们需要循环遍历获取的数据数组
  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)插入数据应为异步操作,使用await
2)三个点(…)是es6语法之扩展运算符
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中

数组对象




定义一个插入时间,可以以时间倒序方式显示歌单(前面显示时间早的歌单,后面显示时间旧的歌单)
获取服务器时间:
createTime: db.serverDate(),





7、歌单数据去重
我们定时获取数据时可能会取到重复的歌单信息,但这并不是我们需要的。
所有需要将读取数据时与数据库中的数据进行比较,不存在才插入数据库
观察到每个歌单信息有
①“_id”指的是当前数据的主鉴,是该数据唯一标识,但由云数据库自动生成的,不作为去重识别标准
②“specialid”是服务端给我们的,是该数据唯一标识,作为去重识别标准,可以判断“specialid”在云数据库中是否存在来实现去重

每次访问playlist都得使用数据库方法,有些长,我们重新定义一个常量来代替
const playlistCollection = db.collection("playlist")
先读取云数据库中的信息存放在dbList。(云函数目前是一次可获取1000条数据,小程序目前一次可获取20条数据。随着官方更新,这个限制会有波动,故而学会突破获取数据条数限制的方法是有必要的,将在【小程序】009 突破获取数据条数的限制 中进行学习)
  const dbList = await playlistCollection.get()//获取云数据库数据

创建一个数组用于存放识别出来的未重复歌单

  const newData = []

循环遍历:

  for(let i = 0,len1 = playlist.length; i < len1; i++){
    let flag = true//标志位,true表不重复
    for(let j = 0,len2 = dbList.data.length;j < len2; j++)
      if(playlist[i].specialid === dblist.data[j].specialid){
        flag = false
        break//重复则直接结束本次数据库的遍历
      }
      if(flag){
        newData.push(playlist[i])
      }
  }
外i循环取到的服务端的数据
设立标志位,true表不重复
内j循环遍历原来云数据库数据
===用于严格比较,一旦相同将flag改为false,并直接结束本次数据库的遍历,减少消耗
判断flag,若不重复(true)调用push()方法:
push() 方法可把它的参数顺序添加到 arrayObject 的尾部。它直接修改 arrayObject,而不是创建一个新的数组。


8、最终效果
1)打开云数据库使用相关高级操作

使用计数操作


调用云函数
再次使用计数操作

总结:
①异步获取云数据库数据
②使用request-promise异步获取字符串数据,转为对象数据
③查重去重
④遍历循环去重数据newData插入数据库
相关代码:
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

const db = cloud.database()

const rp = require('request-promise')

const URL = "服务端接口"

const playlistCollection = db.collection("playlist")

// 云函数入口函数
exports.main = async (event, context) => {
  const dbList = await playlistCollection.get()//获取云数据库数据
  const playlist = await rp(URL).then((res) => {//获取服务端数据
    return JSON.parse(res).data.list
  })

  const newData = []
  for(let i = 0,len1 = playlist.length; i < len1; i++){
    let flag = true//标志位,true表不重复
    for(let j = 0,len2 = dbList.data.length;j < len2; j++)
      if(playlist[i].specialid === dbList.data[j].specialid){
        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
}


API访问小技巧
https://music.163.com/api/playlist/detail?id=2557908184 

http://mobilecdnbj.kugou.com/api/v5/special/recommend?recommend_expire=0&sign=52186982747e1404d426fa3f2a1e8ee4&plat=0&uid=0&version=9108&page=1&area_code=1&appid=1005&mid=286974383886022203545511837994020015101&_t=1545746286
使用技巧:
 
limit:返回数据条数(每页获取的数量),默认为20,可以自行更改
 
offset:偏移量(翻页),offset需要是limit的倍数
 
type:搜索的类型
 
举例,比如limit设置为10,则第一页,第二页分别为:
 
http://music.163.com/api/v1/resource/comments/R_SO_4_483671599?limit=10&offset=0
 
http://music.163.com/api/v1/resource/comments/R_SO_4_483671599?limit=10&offset=10PS:返回的数据格式为json,需要注意的是通过此接口获取的评论数量最多2万条。
模拟接口
由于网上一些教程都是在教学方的服务器写好相关接口,可能会出现修改接口地址或是直接关掉了服务器等情况。其致使我们学习的时候获取数据失败,所以我将选用跨站请求伪(CSRF), 伪造请求头 , 调用官方 API的方式在小程序进行实验,最终效果与我们正常地从服务器获取方式相同

安装
$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git

$ npm install

提醒没有文件夹,我们进入clone下来的文件夹再执行

运行

$ node app.js

可以用任意浏览器检验一下
服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux
$ PORT=4000 node app.js
windows 下使用 git-bash 或者 cmder 等终端执行以下命令 :
$ set PORT=4000 && node app.js
服务器启动默认 host 为localhost,如果需要更改, 可使用以下命令 : Mac/Linux
$ HOST=127.0.0.1 node app.js

windows 下使用 git-bash 或者 cmder 等终端执行以下命令 :

$ set HOST=127.0.0.1 && node app.js

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。