收藏
回答

求助,如何在云数据库中通过一个对象的数量进行排序?

小程序使用云数据库,在同一集合中存储课程标题,内容,点赞用户信息等内容。用户在前台搜索的时候如何通过点赞用户数量进行排序且分页?

代码:

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里面进行排序,这样的话数据量大了太消耗性能了,大家有没有好的解决方案?

回答关注问题邀请回答
收藏

3 个回答

  • o0o有脾气的酸奶
    o0o有脾气的酸奶
    2020-05-07
    const $ = db.command.aggregate
    db.collection('cats').aggregate()
      .addFields({
        starnum: $.size('$stars')
      })
      .sort({
        starnum: -1
      })
      .end()
    


    若认为该回答有用,给回答者点个[ 有用 ],让答案帮助更多的人

    2020-05-07
    有用 2
    回复 2
    • 凉茶
      凉茶
      2020-05-07
      感谢帮助,由于stars可能为空所以在之前需要用project方法构造以下,以下代码可用:
      2020-05-07
      1
      回复
    • o0o有脾气的酸奶
      o0o有脾气的酸奶
      2020-05-07回复凉茶
      恩,方法总比困难多
      2020-05-07
      2
      回复
  • 白天到处飞
    白天到处飞
    2020-05-07

    我有一种不需要聚合的方法,那就是再出一个字段 到云数据库集合里 starnum:0

    每评论一条 对这个字段+1

    然后取的时候 就可以用orderby() 你懂的。

    这样看起来是否更方便呢

    2020-05-07
    有用 1
    回复 2
    • 凉茶
      凉茶
      2020-05-07
      嗯,这确实是一个很取巧的方式,不过这需要在一开始设计数据库的时候就定义好字段。
      感谢您的回答
      2020-05-07
      回复
    • 白天到处飞
      白天到处飞
      2020-05-07回复凉茶
      因为orderby 即使字段不存在也不会报错,我觉得这个方式挺好的。
      2020-05-07
      回复
  • 老张
    老张
    2020-05-07

    $.size第三种有什么问题?

    2020-05-07
    有用 1
    回复 3
    • 凉茶
      凉茶
      2020-05-07
      第三种和第二种的结果一样返回的信息里面不包括title,content的字段
      2020-05-07
      回复
    • 老张
      老张
      2020-05-07回复凉茶
      无语。你需要了解一下arregate.project的用法。
      2020-05-07
      1
      回复
    • 凉茶
      凉茶
      2020-05-07
      感谢提醒,因为项目急确实很多文档没有看全。
      根据提醒以下代码可实现所需效果:
      2020-05-07
      回复
登录 后发表内容
问题标签