首先,无论小程序端单次读取数据库最多20条,云函数单次读取数据库最多100条,这是官方限制,是无法突破的,但是如果你能黑进TX改限制,那我倒头便拜。
所以解决方案就是把单次查询分解成若干次
云函数端
1.首先获得欲查询数据的总数
async function getCountIndexUserId(userId) {
let count = await db.collection('info').where({
"userId": userId
}).count();
return count;
}
获取“info”集合中所有“userId”的值为指定值userId的总数
2.然后编写单次查询函数
单次查询数据总量不超过100
async function getListIndexUserId(userId,skip) {
let list = await db.collection('info').where({
"userId": userId
}).orderBy('_id', 'asc').skip(skip).get();
return list .data;
}
获取“info”集合中所有“userId”的值为指定值,序号从 skip 到 skip+100 的数据
skip使用说明详见官方文档
3.循环查询,然后组合到一起
云函数的main函数如下:
exports.main = async (event, context) => {
let count = await getCountIndexUserId(event.userId);
count = count .total;
let list=[]
for (let i = 0; i < count ; i += 100) {
list = quesionList.concat(await getListIndexUserId(event.userId, i));
}
return list ;
}
结束,需要注意的是,云函数单次返回的数据不能超过1M,如果需要超过1M,则需要使用小程序端的数据查询20条20条的进行组合了
小程序端
思路与云函数端一样,不同的是小程序端不允许await
,需要用Promise
方法实现
1.获取总数
function getListCount(openid) {
return new Promise((resolve, reject) => {
db.collection('info').where({
"studyUserId": openid
}).count().then(res => {
resolve(res.total);
}).catch(e => {
console.log(e)
reject("查询失败")
})
})
}
这里查询数据库集合“info”中“studyUserId”的值为给定值“openid”的所有数据总数
2.单次查询函数
function getListIndexSkip(openid, skip) {
return new Promise((resolve, reject) => {
let statusList = []
let selectPromise;
if (skip > 0) {
selectPromise = db.collection('info').where({
"studyUserId": openid
}).skip(skip).get()
} else {
//skip值为0时,会报错
selectPromise = db.collection('info').where({
"studyUserId": openid
}).get()
}
selectPromise.then(res => {
resolve(res.data);
}).catch(e => {
console.error(e)
reject("查询失败!")
})
})
}
需要注意的是,小程序端的数据库查询不允许skip设置为0,否则会报错,有哪位大神知道TX为什么这么设计,还请赐教
3.循环查询,整合数据
getListCount(openid).then(res => {
let count = res
let list = []
for (let i = 0; i < count ; i += 20) {
getListIndexSkip(openid, i).then(res => {
list = list.concat(res);
if (list.length == count ) {
resolve(list)
}
})
.catch(e => {
console.error(e)
reject("查询失败")
})
}
})
})