MongoDB中实现多表联查的实例教程

 更新时间:2022年07月07日 15:28:41   作者:山维空间  
数据库应用在我们的生活中是很常见的,在编辑一些应用以及软件的时候都需要用到数据库来存储数据,下面这篇文章主要给大家介绍了关于MongoDB中实现多表联查的相关资料,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

前些天遇到一个需求,不复杂,用 SQL 表现的话,大约如此:

SELECT *
FROM db1 LEFT JOIN db2 ON db1.a = db2.b
WHERE db1.userId='$me' AND db2.status=1

没想到搜了半天,我厂的代码仓库里没有这种用法,各种教程也多半只针对合并查询(即只筛选 db1,没有 db2 的条件)。所以最后只好读文档+代码尝试,终于找到答案,记录一下。

  • 我们用 mongoose 作为连接库
  • 联查需要用 $lookup
  • 如果声明外键的时候用 ObjectId,就很简单:
// 假设下面两个表 db1 和 db2
export const Db1Schema = new mongoose.Schema(
  {
    userId: { type: String, index: true },
    couponId: { type: ObjectId, ref: Db2Schema },
  },
  { versionKey: false, timestamps: true }
);
export const Db2Schema = new mongoose.Schema(
  {
    status: { type: Boolean, default: 0 },
  },
  { versionKey: false, timestamps: true }
);

// 那么只要
db1Model.aggregate([
  {
    $lookup: {
      from: 'db2', // 目标表
      localField: 'couponId', // 本地字段
      foreignField: '_id', // 对应的目标字段
      as: 'source',
  },
  {
    $match: [ /* 各种条件 */ ],
  },
]);

但是我们没有用 ObjectId,而是用 string 作为外键,所以无法直接用上面的联查。必须在 pipeline 里手动转换、联合。此时,当前表(db1)的字段不能直接使用,要配合 let,然后加上 $$ 前缀;连表(db2)直接加 $ 前缀即可。

最终代码如下:

mongo.ts

// 每次必有的条件,当前表的字段用 `$$`,连表的字段用 `$`
const filter = [{ $eq: ['$$userId', userId] }, { $eq: ['$isDeleted', false] }];
if (status === Expired) {
  dateOp = '$lte';
} else if (status === Normal) {
  dateOp = '$gte';
  filter.push({ $in: ['$$status', [Normal, Shared]] });
} else {
  dateOp = '$gte';
  filter.push({ $eq: ['$$status', status] });
}
const results = await myModel.aggregate([
  {
    $lookup: {
      from: 'coupons',
      // 当前表字段必须 `let` 之后才能用
      let: { couponId: '$couponId', userId: '$userId', status: '$status' },
      // 在 pipeline 里完成筛选
      pipeline: [
        {
          $match: {
            $expr: {
              // `$toString` 是内建方法,可以把 `ObjectId` 转换成 `string`
              $and: [{ $eq: [{ $toString: '$_id' }, '$$couponId'] }, ...filter, { [dateOp]: ['$endAt', new Date()] }],
            },
          },
        },
        // 只要某些字段,在这里筛选
        {
          $project: couponFields,
        },
      ],
      as: 'source',
    },
  },
  {
    // 这种筛选相当 LEFT JOIN,所以需要去掉没有连表内容的结果
    $match: {
      source: { $ne: [] },
    },
  },
  {
    // 为了一次查表出结果,要转换一下输出格式
    $facet: {
      results: [{ $skip: size * (page - 1) }, { $limit: size }],
      count: [
        {
          $count: 'count',
        },
      ],
    },
  },
]);

同事告诉我,这样做的效率不一定高。我觉得,考虑到实际场景,他说的可能没错,不过,早晚要迈出这样的一步。而且,未来我们也应该慢慢把外键改成 ObjectId 类型。

总结

到此这篇关于MongoDB中实现多表联查的文章就介绍到这了,更多相关MongoDB多表联查内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • MongoDB日常使用的技巧与注意事项汇总

    MongoDB日常使用的技巧与注意事项汇总

    这篇文章主要给大家总结介绍了关于MongoDB日常使用的一些技巧与注意事项,文中通过示例代码介绍的非常详细,对大家学习或者使用MongoDB具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • 28个MongoDB经典面试题详解

    28个MongoDB经典面试题详解

    这篇文章主要介绍了28个MongoDB经典面试题详解,需要的朋友可以参考下
    2020-02-02
  • MongoDB时间戳转日期及日期分组实例代码

    MongoDB时间戳转日期及日期分组实例代码

    时间戳(timestamp)通常是一个字符序列,唯一地标识某一刻的时间,下面这篇文章主要给大家介绍了关于MongoDB时间戳转日期及日期分组的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • MongoDB数据库简介与安装方法

    MongoDB数据库简介与安装方法

    这篇文章介绍了MongoDB数据库简介与安装方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03
  • SpringBoot?整合mongoDB并自定义连接池的示例代码

    SpringBoot?整合mongoDB并自定义连接池的示例代码

    这篇文章主要介绍了SpringBoot?整合mongoDB并自定义连接池?,整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数据库,对整合过程及实例代码感兴趣的朋友跟随小编一起看看吧
    2022-02-02
  • 解决mongodb在ubuntu下启动失败,提示couldn‘t remove fs lock errno:9 Bad file descriptor的错误

    解决mongodb在ubuntu下启动失败,提示couldn‘t remove fs lock errno:9 Bad

    之前MongoDB启动的时候是蛮正常的,不知道后来启动报错了,就把粘贴出来查询了。经过一番百度,才找的处理的办法,分享给大家
    2014-08-08
  • MongoDB入门教程之分片技术详解

    MongoDB入门教程之分片技术详解

    这篇文章主要介绍了MongoDB入门教程之分片技术详解,分片是mongodb中的另一种集群技术,需要的朋友可以参考下
    2014-08-08
  • MongoDB特点与体系结构等简介

    MongoDB特点与体系结构等简介

    今天小编就为大家分享一篇关于MongoDB特点与体系结构等简介,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 给MongoDB添加用户权限方法分享

    给MongoDB添加用户权限方法分享

    这篇文章主要介绍了给MongoDB添加用户权限方法分享,十分的细致全面,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • Mongodb启动报错完美解决方案:about to fork child process,waiting until server is ready for connections.

    Mongodb启动报错完美解决方案:about to fork child pr

    在使用命令行启动 MongoDB 的时候报错:about to fork child process, waiting until server is ready for connections.forked process: 50411,造成这个报错的原因是 “MongoDB” 服务没有正常的关闭,在终端连接非正常断开后,再次执行 MongoDB 的时候报错
    2023-04-04

最新评论

?


http://www.vxiaotou.com