龙啸泽渊
龙啸泽渊
  • 发布:2020-03-22 10:44
  • 更新:2020-03-26 17:28
  • 阅读:1185

有一个云数据库的小问题,卡住几天了,群里没人回,希望给个思路

分类:uniCloud

有一个blog表,然后根据它的分类id查找出多条记录,然后要到blogvote表查根据这个id有多少条点赞数量,和查询当前用户有没有点赞,这种该怎么写。。我是先查出来记录。然后for循环里补上每条的点赞数量和是否点赞,这个耗时2512ms。。太久了,
博客表包含了一个cate_id,贴上blogvote表
我看文档,关联表用lookup。但是没法加条件,如果用addFields,又不知道怎么继承当前查询的blog_id,还有一个就是查询数量的,好像也只能用addFields

2020-03-22 10:44 负责人:无 分享
已邀请:
DCloud_uniCloud_WYQ

DCloud_uniCloud_WYQ

'use strict';  
const db = uniCloud.database()  
exports.main = async () => {  
  let userId = 'user-1'  
  const $ = db.command.aggregate  
  let res = await db.collection('blog').aggregate().lookup({  
    localField: '_id',  
    foreignField: 'blogId',  
    from: 'zan',  
    as: 'zanList'  
  }).addFields({  
    zanCount: $.size('$zanList'),  
    zaned: $.anyElementTrue([$.map({  
      input: '$zanList',  
      as: 'zanItem',  
      in: $.eq(['$$zanItem.userId', userId])  
    })])  
  }).lookup({  
    localField: 'author',  
    foreignField: '_id',  
    from: 'user',  
    as: 'author'  
  }).unwind('$author').project({  
    'author._id': 0,  
    zanList: 0  
  }).end()  
  return res  
};

多研究研究吧,磨刀不误砍柴工

  • 龙啸泽渊 (作者)

    好的,感谢您的教导,十分抱歉打扰了这么久,我实在是卡住了没办法

    2020-03-26 17:38

DCloud_uniCloud_WYQ

DCloud_uniCloud_WYQ

有多少条点赞数量,和查询当前用户有没有点赞 这两个你要放到一步里面完成?

  • 龙啸泽渊 (作者)

    就是说我目前是查找出来blog,然后循环这个blog,每条补上await db.collection xxxx查数量,然后 await db.collection xxxx查是否点赞,因为循环里放这种查询,导致速度特别慢

    2020-03-23 23:28

DCloud_uniCloud_WYQ

DCloud_uniCloud_WYQ

你的意思是在做一个blog列表之类的东西是吗?一次返回多个blog,并且要在这多个blog内添加点赞数量和用户是否点赞是吗?如果是的话可以参考下面的示例:

db_init.json

{  
  "blog": {  
    "data": [{  
        "_id": "blog-1",  
        "content": "11111111"  
      },  
      {  
        "_id": "blog-2",  
        "content": "22222222"  
      },  
      {  
        "_id": "blog-3",  
        "content": "33333333"  
      }  
    ]  
  },  
  "zan": {  
    "data": [  
      {  
        "_id": "zan-1",  
        "blogId": "blog-1",  
        "userId": "user-1"  
      },  
      {  
        "_id": "zan-2",  
        "blogId": "blog-2",  
        "userId": "user-2"  
      },  
      {  
        "_id": "zan-3",  
        "blogId": "blog-1",  
        "userId": "user-2"  
      }  
    ]  
  },  
  "user": {  
    "data": [  
      {  
        "_id": "user-1",  
        "name": "user-name-1"  
      },  
      {  
        "_id": "user-2",  
        "name": "user-name-2"  
      }  
    ]  
  }  
}

云函数代码

'use strict';  
const db = uniCloud.database()  
exports.main = async () => {  
  let userId = 'user-1'  
  const $ = db.command.aggregate  
  let res = await db.collection('blog').aggregate().lookup({  
    localField: '_id',  
    foreignField: 'blogId',  
    from: 'zan',  
    as: 'zanList'  
  }).addFields({  
    zanCount: $.size('$zanList'),  
    zaned: $.anyElementTrue([$.map({  
      input: '$zanList',  
      as: 'zanItem',  
      in: $.eq(['$$zanItem.userId', userId])  
    })])  
  }).project({  
    zanList: 0  
  }).end()  
  return res  
};
  • 龙啸泽渊 (作者)

    对对,非常感谢,但是zan表还需要加上一个status>0的条件,因为有的被逻辑删除了,请问该从哪里加......

    2020-03-26 12:12

  • DCloud_uniCloud_WYQ

    回复 龙啸泽渊: https://uniapp.dcloud.io/uniCloud/cf-database?id=filter 加在addFields之前,聚合操作的文档很长,但还是建议仔细看一遍

    2020-03-26 12:20

  • 龙啸泽渊 (作者)

    回复 DCloud_uniCloud_WYQ: 就是没有一个例子,硬生生消化不会。。如果不是您上面发的那串,我都想不出来还可以这样用

    2020-03-26 12:25

  • 龙啸泽渊 (作者)

    回复 DCloud_uniCloud_WYQ: 这个我大概清楚了,在addFields之前放一个filter,但是这样是查出所有数据在聚合,是最好的方式吗?有没有更快的方法,比如查询表的时候就加上这个status判断,这样返回的数据就比较少些

    2020-03-26 12:27

  • DCloud_uniCloud_WYQ

    回复 龙啸泽渊: 有的,但是阿里云的mongoDB版本有点低,不支持,https://uniapp.dcloud.io/uniCloud/cf-database?id=%e8%87%aa%e5%ae%9a%e4%b9%89%e8%bf%9e%e6%8e%a5%e6%9d%a1%e4%bb%b6%e3%80%81%e6%8b%bc%e6%8e%a5%e5%ad%90%e6%9f%a5%e8%af%a2

    2020-03-26 12:30

  • 龙啸泽渊 (作者)

    回复 DCloud_uniCloud_WYQ: 可以让他们升级下吗....为啥用3.4

    2020-03-26 12:34

  • 龙啸泽渊 (作者)

    回复 DCloud_uniCloud_WYQ: 还有一个问题想请教。。。我lookup了user表,但是我只想返回user的nick和image,该怎么拼,我是加上了 .project({

    user: $.arrayElemAt(['$userinfo', 0]),

    }),然后我又.project({

    user._id: 1,

    user.nick: 1,

    user.image: 1

    })

    但是返回Unexpected token .

    /tmp/function/__index.js:38

    user._id: 1,

    意思好像是不能直接这样project

    2020-03-26 12:44

  • DCloud_uniCloud_WYQ

    回复 龙啸泽渊: 可以用project加map实现,你这么写是有语法错误的

    2020-03-26 13:36

  • DCloud_uniCloud_WYQ

    回复 龙啸泽渊: 文档确实有错误,也不是num是total,你可以注意这里的project的用法,就是给某个某个字段赋值。你的lookup user是在哪部执行的?这步是为了查询blog的作者信息吗?如果是的话直接使用unwind https://uniapp.dcloud.io/uniCloud/cf-database?id=unwind再用project即可,你还是多看看文档吧。这样问效率太低了

    2020-03-26 15:52

  • 龙啸泽渊 (作者)

    回复 DCloud_uniCloud_WYQ: 我就是不明白一点其实,就是怎么只保留想要的几个字段,map,unwind,都是把lookup出的user:[{"_id":"1","nick",xxxxxxxxx}],拿出来做成一个我命名的对象,如变成了user:{"_id":"1","nick",xxxxxxxxx},但是这个对象该怎么操作只保留那几个字段,project并不能以对象 . 字段的方式操作

    2020-03-26 17:06

该问题目前已经被锁定, 无法添加新回复