向 MongoDB 中的 $lookup 结果添加一个字段

2024-02-04

我正在尝试使用 node.js MongoDB 驱动程序向查找结果添加一个字段。用户有两种提要 1. 他或她自己的提要和 2. 共享提要。所以我需要同时获得两者,然后将它们结合起来。这是我原来的查询,效果很好:

client.db('atlas').collection('users').aggregate([
    { $match: { user_id: userId } },
    {
      $lookup: {
        from: 'feeds',
        localField: "user_id",
        foreignField: "user_id",
        as: "feeds"
      }
    },
    {
      $lookup: {
        from: 'shares',
        localField: 'email',
        foreignField: "share",
        as: "shares"
      }
    },
    {
      $lookup: {
        from: 'feeds',
        localField: 'shares.feed_id',
        foreignField: "_id",
        as: "shared_feeds"
      }
    },
    {
      $addFields: { 'shared_feeds.share': true }
    },
    {
       $project: {
         user_id: 1,
         first_name: 1,
         last_name: 1,
         email: 1,
         feeds: { $concatArrays: [ '$feeds', '$shared_feeds' ] }
       }
    }
])

但我想在“提要”的第二次查找中添加一个字段,因此我尝试使用如下管道:

{
  $lookup: {
    from: 'feeds',
    let: { shareId: '$shares.feed_id' },
    pipeline: [
      { $match: { '_id': ObjectId('$$shareId') } }
    ],
    as: "shared_feeds"
  }
}

但我无法让比赛发挥作用ObjectId。该变量似乎不起作用。我究竟做错了什么?

样本集合: 用户:

[
    {
    "_id" : ObjectId("5e970a1f797c08e70ce4e2f6"),
    "user_id" : "testuserid",
    "first_name" : "Jacopo",
    "last_name" : "Belbo",
    "email" : "[email protected] /cdn-cgi/l/email-protection"
   }
]

feeds:

 [
  {
      "_id" : ObjectId("5f29b02318ecbf0083f01f1e"),
      "name" : "test csv",
      "user_id" : "auth0|5eac6faa1cc1ac0c147b5b16",
      "type" : "feed",
      "created_at" : ISODate("2020-08-04T18:59:47.640Z"),
      "updated_at" : ISODate("2020-08-04T18:59:47.640Z")
  },
  {
    "_id" : ObjectId("5f29b05d18ecbf0083f01f1f"),
    "name" : "typtap-small",
    "user_id" : "auth0|5f1b2da0e60194003d714680",
    "url" : "http://localstack:4572/atlas/usertes",
    "type" : "feed",
    "created_at" : ISODate("2020-08-04T19:00:45.886Z"),
    "updated_at" : ISODate("2020-08-04T19:00:45.886Z")
  }
]

shares:

[
    {
    "_id" : ObjectId("5f29b07318ecbf0083f01f20"),
    "feed_id" : ObjectId("5f29b05d18ecbf0083f01f1f"),
    "share" : "[email protected] /cdn-cgi/l/email-protection",
    "type" : "share",
    "recipient" : "email",
    "created_at" : ISODate("2020-08-04T19:01:07.668Z"),
    "updated_at" : ISODate("2020-08-04T19:01:07.668Z")
}
]

In let: { shareId: '$shares.feed_id' },你正在通过ObjectId to shareId。所以你不能用ObjectId() in match阶段。当您在查找中使用管道来查找多个条件时只需使用$expr

    {
      $match: {
        $expr: {
          $eq: [
            "$$shareId",
            "$_id"
          ]
        }
      }
    }

更新1。

当你在里面使用管道时$lookup,你需要使用$expr, Refer 查找中的 $expr https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#specify-multiple-join-conditions-with-lookup。一旦你得到输出,你就会有一个数组,所以$unwind它并进行连接。然后将其分组以避免重复。

Working 蒙戈游乐场 https://mongoplayground.net/p/JOKKv1rKCiy

Update 2

蒙戈脚本

[
  {
    $match: {
      user_id: "testuserid"
    }
  },
  {
    $lookup: {
      from: "feeds",
      localField: "user_id",
      foreignField: "user_id",
      as: "feeds"
    }
  },
  {
    $lookup: {
      from: "shares",
      localField: "email",
      foreignField: "share",
      as: "shares"
    }
  },
  {
    $unwind: {
      path: "$shares",
      preserveNullAndEmptyArrays: false
    }
  },
  {
    $lookup: {
      from: "feeds",
      let: {
        shareId: "$shares.feed_id"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: [
                "$$shareId",
                "$_id"
              ]
            }
          }
        }
      ],
      as: "shared_feeds"
    }
  },
  {
    $group: {
      _id: "$_id",
      user_id: {
        $first: "$user_id"
      },
      first_name: {
        $first: "$first_name"
      },
      last_name: {
        $first: "$last_name"
      },
      email: {
        $first: "$email"
      },
      feeds: {
        $first: "$feeds"
      },
      shares: {
        $addToSet: "$shares"
      },
      shared_feeds: {
        $addToSet: "$shared_feeds"
      }
    }
  },
  {
    $addFields: {
      shared_feeds: {
        $reduce: {
          input: "$shared_feeds",
          initialValue: [],
          in: {
            $setUnion: [
              "$$this",
              "$$value"
            ]
          }
        }
      }
    }
  },
  {
    $addFields: {
      "shared_feeds.share": true
    }
  },
  {
    $project: {
      user_id: 1,
      first_name: 1,
      last_name: 1,
      email: 1,
      feeds: {
        $concatArrays: [
          "$feeds",
          "$shared_feeds"
        ]
      }
    }
  }
]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

向 MongoDB 中的 $lookup 结果添加一个字段 的相关文章

随机推荐

  • 如何强制刷新文件

    假设我有以下代码 include
  • Android上传大文件

    我对 Android 开发非常陌生 我正在尝试将大小为 25 到 50 MB 的文件上传到 Web 服务器 但出现内存不足错误 我在过去的两天里苦苦挣扎 不知道我哪里出了问题 对我哪里出错有什么建议吗 我正在处理的代码是 private F
  • Firebase 部署失败 - 找不到functions.yaml。必须使用http发现[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在尝试部署 firebase 云功能 但不断收到此错误 最奇怪的部分是 我让它工作正常 但从 firebase 与云视觉对话切
  • Angular 4 项目中功能性 e2e 量角器测试中的模拟休息调用

    我们有一个庞大的项目 我们编写了很多测试用例 在我们的 e2e 功能测试用例中涵盖了很多真实场景 的用户行为 随着测试的进行 它会进行大量的休息调用来完成测试用例 当我们在酱汁实验室中覆盖不同的浏览器时 它会增加 5 9 倍 我想要的是模拟
  • 如何在Dockerfile中访问云运行环境变量

    我已经构建了一个容器化的 python 应用程序 它使用本地运行没有问题 env文件和一个docker compose yml编译的文件撰写构建 然后我就可以像这样在 Dockerfile 中使用变量 ARG APP USR ENV APP
  • 如何使FactoryGirl.create影响另一条记录的属性?

    在网上商店应用程序中 通常在booking一个产品的预订控制器创建动作执行order save这反过来又激活必要的 before save 方法order sum of all bookings 当为查看订单列表的管理员构建 RSpec 测
  • 以字段名称作为参数的表达式谓词

    我使用这段代码 在 stackoverflow 上找到 来生成谓词 static class BuilderPredicate public static Expression
  • 错误 1 ​​libavcodec.so 文件格式无法识别 Android GL 动态壁纸

    我正在尝试为 android 制作一个动态壁纸 播放位于 android asset 设备上的 mp4 视频 以我正在使用的示例为例 它实际上在运行时将文件复制到 SD 卡 无关紧要 我找到了这个example https github c
  • Angular 5 按日期排序

    我有一张课程表 我想按日期排序 由于 Angular 5 没有 orderBy 管道 并且到目前为止我找到的所有解决方案都只能应用于数字和字符串 如果有人可以帮助我 我将不胜感激 这是我的桌子的主体 tbody tr th lesson d
  • 如何使用 sed (或类似的)删除两个 html 标签之间的所有行?

    我有一个如下所示的文件 lt stuff gt lt stuff gt 我试图删除 HEAD 标签之间 包括 HEAD 标签 之间的所有内容 但似乎无法使其工作 我想 sed i e s lt HEAD gt g file HTML 应该可
  • 将逻辑 and 应用于布尔值列表

    考虑以下 Scala 中的布尔值列表 List true false false true 您将如何使用foldRight 或foldLeft 模拟对列表中的所有值执行逻辑AND 的功能 而不是使用foldLeft Right 您还可以使用
  • 为什么切片[:-0]在Python中返回空列表

    今天在编写一些单元测试时偶然发现了一些有点令人困惑的事情 blah a b c blah 3 blah 2 a blah 1 a b blah 0 我一生都无法弄清楚为什么blah 0 应该是这样 该模式似乎绝对表明它应该是 a b c 任
  • Webclient 双向使用二进制文件

    网络客户端 http msdn microsoft com en us library system net webclient 28v vs 95 29 aspx用于将指令文件 最多 1 兆字节 上传到服务器 并以二进制数据形式接收该操作
  • 将自定义对象附加到 Qt 中的 QStandardItem

    我在用着QTreeView向用户显示一些数据 我想要的是将一个实际对象附加到使用表示的每个节点QStandardItem 将对象引用保存到QStandardItem QStandardItem child new QStandardItem
  • Hibernate FetchMode SELECT 与 JOIN

    我有以下课程 Entity public class TestContentElementResponse Id GeneratedValue strategy GenerationType AUTO protected Long id O
  • 通过 SSL 传递时的 Cookie 安全性

    我是否正确地认为 如果您通过 SSL 加密请求传递会话 cookie 则该 cookie 只能由能够直接访问 cookie 发送到的计算机或发送 cookie 的服务器的攻击者读取 前提是他们无法破解加密 SSL 加密所有流量 包括标头 其
  • PHP - 未定义的变量

    我正在做一些练习PHP 和 MySQL 初学者塔克先生 在他的示例中一切正常 但在我的电脑上出现错误 注意 未定义变量 passwordRetrieved 在 C wamp www loginForm php 第 39 行 此示例的完整 P
  • 我们如何在VB.Net控制台应用程序中使用定时器控件?

    我正在尝试在控制台应用程序中使用计时器控件 Friend WithEvents XTIMER As System Windows Forms Timer 我正在设置它的所有属性 我已将间隔设置为 15000 毫秒 但即使我将计时器控件的启用
  • 无法在 windows7 上打开请求的 SVN 文件系统

    在 Windows 7 上使用 subversion 配置 apache httpd 时 出现以下错误 我已经安装了不同类型版本的 SVN 和 apache 我仍然面临这个问题 可以请有人帮助我解决这个问题 svn version 1 9
  • 向 MongoDB 中的 $lookup 结果添加一个字段

    我正在尝试使用 node js MongoDB 驱动程序向查找结果添加一个字段 用户有两种提要 1 他或她自己的提要和 2 共享提要 所以我需要同时获得两者 然后将它们结合起来 这是我原来的查询 效果很好 client db atlas c