let openid=cloud.getWXContext().OPENID
const db = cloud.database()
const $ = db.command.aggregate
const _ = db.command
return await db.collection('goods_list').aggregate()
.match({
goodsFlag:'1'
})
.lookup({
from: 'tuan_list',
let: {
goods_id:'$_id'
},
pipeline: $.pipeline()
.match(_.expr($.and([
$.eq(['$tuanZhangOpenId',openid]),
$.neq(['$goodsId','$$goods_id'])
])))
.project({
_id:0,
goodsList:$.eq(['$goodsList'.length,0]),
tuanZhangOpenId:1,
goodsId:1
})
.done(),
as: 'goodsList',
})
.end()
.then(res => res)
.catch(err => res)
数据结构:
goods_list(只有两条数据)
tuan_list(只有一条数据)
===========================
返回结果:
疑问:
在我的pipeline的match中,条件控制项,ID要求不相等的这个$.neq(['$goodsId','$$goods_id'])未起到作用吗?
还是说理论上子表的条件不优先?
需求结果:
result只返回goodsList有值的结果,即“牛肉”的那条数据。
PS:除了在then里写JS循环判断再重新push后return这种方式,可不可以在match里或其他项上做条件控制?
感谢。
-
如果我用sql写的话,思路是下面这样:
SELECT a.* from a left join b
on b.aid!=a.id
where a.goodsFlag=1 and b.aid is not null
在微信云开发中,第一个match的条件,是先执行再lookup,还是先lookup再执行第一个match?
如果我想判断goodsList数组的长度,我尝试过在第一个match里追加goodsList:$.eq(['$goodsList'.length,0]),但失败了。
所以是不是第一个match要先于lookup呢?
我在lookup之后match去判断数组长度,好像也没起到作用。
-
另外,如果lookup的左外联性质,无法改变,它不能像sql一样在最外集合追加where 子表 is not null的话,我想我可能要改变表结构了。
那么,如果我使用文档型数据库的话,单条数据的goodsList字段[],存放过多的集合,会不会对查询造成压力。
比如:
{goodsName:测试商品, goodsPrice:10.00, tuanList[1,2,3,4,5……10000]}
当我去筛选某些值 in tuanList的时候,效率高吗?
不太了解云开发的数据库效率。
在云开发数据库中,是不是更倾向于文档型结构?传统的关系型结构,反而会带来麻烦和效率问题呢?
呃。。。
按照传统SQL去套,最后弄明白了。
首先数组的关键字错了,用_.size()是正确的。
其次,要在最后lookup后再match goodsList:_.size(1)
(我用size1是为了方便,实际情况肯定不止1,可以再套个gt试试,另外,官方文档中,对match提到:注意
match
阶段和其他聚合阶段不同,不可使用聚合操作符,只能使用查询操作符。所以如果要用聚合函数,需要_.expr吧,就像pipeline里一样,我还没有试,遇到同样问题的伙伴,自己试一下吧)然后成功了。
虽然成功了,但我决定还是要重新设计数据结构。
我认为这种效率应该真的不高,大家可以查看日志里的内存性能损耗,看自己的业务执行情况。
最后:
第一次开发小程序,也从没用过vue或者node。
这种磕磕绊绊的尝试,才能对比出与java和jsp的区别吧,印象才深刻。
代码如下(格式不整齐,有一些冗余的,有一些无效的,请忽略,我也在尝试的路上):
const openid=cloud.getWXContext().OPENID const db = cloud.database() const $ = db.command.aggregate const _ = db.command return await db.collection('goods_list').aggregate() .match({ goodsFlag:'1' }) .lookup({ from: 'tuan_list', let: { goods_id:'$_id', oid:openid }, pipeline: $.pipeline() .match(_.expr($.and([ $.eq(['$tuanZhangOpenId','$$oid']), $.neq(['$goodsId','$$goods_id']) ]))) .project({ _id:0, goodsList:$.eq(['$goodsList'.length,0]), tuanZhangOpenId:1, goodsId:1 }) .done(), as: 'goodsList', }) .match({ goodsList:_.size(1) }) .end() .then(res => res) .catch(err => res) // return res }
我看这个帖子浏览量也不低,估计还有一些刚接触的伙伴,遇到了同样的问题,解决过程中不断的搜帖子,我作为一个小程序新手,尽量帮其他新手留下一些痕迹吧,也为其他老手留下更多时间,解决非这种low的问题或帖子。
经验标注:
1.小程序数据结构很关键;
2.官方文档要看,但更重要的是自己的思维。
3.有其他开发基础,尤其是数据库的,发散思维结合经验。
4.无经验的,还是多搜帖子多看多问吧。