小程序使用云数据库,在同一集合中存储课程标题,内容,点赞用户信息等内容。用户在前台搜索的时候如何通过点赞用户数量进行排序且分页?
代码:
courses集合:
[{
title:'111',
content: 'xxx',
stars: [{
name: 'name1',
open_id: 'xxx'
}]
},{
title:'222',
content: 'xxx',
stars: [{
name: 'name1',
open_id: 'xxx'
},{
name: 'name2',
open_id: 'xxx1'
}]
},{
title:'333',
content: 'xxx',
}]
希望实现的排序结果:
[{
title:'222',
content: 'xxx',
stars: [{
name: 'name1',
open_id: 'xxx'
},{
name: 'name2',
open_id: 'xxx1'
}]
},{
title:'111',
content: 'xxx',
stars: [{
name: 'name1',
open_id: 'xxx'
}]
},{
title:'333',
content: 'xxx',
}]
尝试的解决方案:
第一种:
db.collection('courses').orderBy('stars', 'desc').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
此方法无法正确实现通过stars的数量进行排序,况且如果stars不存在的话还会报错,如果存在orderBy('stars.length', 'desc')这种的话就更好了。
第二种:
db.collection('courses')
.aggregate()
.unwind({
path: '$stars',
preserveNullAndEmptyArrays: true
})
.sortByCount('$_id')
.end()
这种也不可以,得到的结果类似于[{"_id":"xxx", count: xxx},{"_id":"xxx", count: xxx},{"_id":"xxx", count: xxx}], 无法获取title, content等的内容
第三种:
const $ = db.command.aggregate
db.collection('cats').aggregate()
.project({
stars: $.concatArrays([{"name":"good"}]),
})
.project({
starnum: $.size('$stars')
}).sort({
starnum: -1
})
.end()
这种也存在问题。
现在我想到的唯一解决方案是取出全部数据然后在js里面进行排序,这样的话数据量大了太消耗性能了,大家有没有好的解决方案?
const $ = db.command.aggregate db.collection('cats').aggregate() .addFields({ starnum: $.size('$stars') }) .sort({ starnum: -1 }) .end()
若认为该回答有用,给回答者点个[ 有用 ],让答案帮助更多的人
const $ = db.command.aggregate
db.collection('cats').aggregate()
.project({
stars: $.concatArrays([]),
title: 1,
content: 1
})
.addFields({
starnum: $.size('$stars')
})
.sort({
starnum: -1
})
.end()
const $ = db.command.aggregate
db.collection('cats').aggregate()
.addFields({
starnum: $.cond({
if: $.ifNull(['$stars', true]),
then: 0,
else: $.size('$stars')
})
})
.sort({
starnum: -1
})
.project({
stars: $.ifNull(['$stars', []]),
title: 1,
content: 1
})
.end()
我有一种不需要聚合的方法,那就是再出一个字段 到云数据库集合里 starnum:0
每评论一条 对这个字段+1
然后取的时候 就可以用orderby() 你懂的。
这样看起来是否更方便呢
感谢您的回答
$.size第三种有什么问题?
根据提醒以下代码可实现所需效果:
const $ = db.command.aggregate
db.collection("courses").aggregate()
.project({
stars: $.concatArrays([]),
title: 1
})
.project({
starnum: $.size('$stars'),
title: 1
}).sort({
starnum: -1
}).end()