微信小程序使用lookup进行多表联合,有两种方式
方式1:
将输入记录(输入记录:就是源数据表集合)的一个字段和被连接集合的一个字段进行相等匹配时,采用以下定义:
lookup({
from: <要连接的集合名>,
localField: <输入记录的要进行相等匹配的字段>,
foreignField: <被连接集合的要进行相等匹配的字段>,
as: <输出的数组字段名>
})
看官方文档案例即可。
方式2:
如果需要指定除相等匹配之外的连接条件,或指定多个相等匹配条件,或需要拼接被连接集合的子查询结果,那可以使用如下定义:
lookup({
from: <要连接的集合名>,
let: { <变量1>: <表达式1>, ..., <变量n>: <表达式n> },
pipeline: [ <在要连接的集合上进行的流水线操作> ],
as: <输出的数组字段名>
})
(下面的案例 筛选子结果需要保留的字段)
// 云函数入口文件
const cloud = require('wx-server-sdk');
const db = cloud.database();
const _ =db.command;
const $ = _.aggregate;
//初始化
cloud.init({
env:cloud.DYNAMIC_CURRENT_ENV
})
exports.main = async(event,context)=>{
return new Promise((resolve,reject)=>{//采用await的方式,会返回result null,不解
db.collection('cloudOrder').aggregate().lookup({
from:'cloudUserInfo',//要联合的表
let:{//如果下方的pipeline中需要用到输入记录(即cloudOrder表)中的变量,必须在let中定义
order_openid:'$_openid'//此处的_openid为cloudOrder中的字段
},
pipeline:$.pipeline().match(_.expr($.eq(['$_openid','$$order_openid'])))
//pipeline指定要在被连接集合中运行的聚合操作,即对联合的表cloudUserInfo进行聚合操作;match为过滤操作;_.expr为执行表达式命令;$.eq(['元素1','元素2'])聚合比较运算表达式,返回值为true/false,对元素1和元素2进行相等判断;$_openid为要联合的表cloudUserInfo中的字段,$$order_openid为let中定义的变量
.project({
_id:0,
avatarUrl:1
}).done(),//project为指定连接集合中需要保留或删除的字段,_id不显示,只显示avatarUrl;done()为pipeline操作结束
as:'userInfo'//返回的结果集,userInfo:[{avatarUrl:'***'}]
})
.lookup({
from:'cloudUserInfo',
let:{
order_acceptOpenid:'$acceptOpenid'
},
pipeline:$.pipeline().match(_.expr($.eq(['$_openid','$$order_acceptOpenid']))).project({
_id:0,
acceptAvatar:'$avatarUrl',
acceptNickName:'$nickName',
acceptPhone:'$phone'
}).done(),
as:'acceptInfo'
})
.replaceRoot({
newRoot:$.mergeObjects([ $.arrayElemAt(['$userInfo',0]),$.arrayElemAt(['$acceptInfo',0]),'$$ROOT'])
}).project({
userInfo:0,
acceptInfo:0
})
.sort({'publicTime':1}).end().then(res=>{
resolve({status:"success",msg:res})
}).catch(err=>{
reject({status:"fail",msg:err})
})
})
}