【问题标题】:Join like in mongodb with arrays of documents and conditions在 mongodb 中加入文档和条件数组
【发布时间】:2021-06-02 15:53:50
【问题描述】:

我正在努力创建一个 MongoDB 查询以使用聚合,以便像条件查询一样执行连接。 这是我的输入:

'东西'集合:

{
    _id : 1
    users : [
        {
            userId : 00001,
            role : "creator"
        },
        {
            userId : 00002,
            role : "spectator"
        }
    ]
}
{
    _id : 2
    users : [
        {
            userId : 00002,
            role : "creator"
        },
        {
            userId : 00001,
            role : "spectator"
        }
    ]
}

'用户'收藏:

{
    _id : 00001,
    name : "John"
}
{
    _id : 00002,
    name : "Doe"
}

我想获取给定“事物”_id 的创建者的姓名/信息,并为 _id = 1 获取类似的内容:

{
    _id : 00001,
    name : "John"
}

这是迄今为止我去过的地方:

db.Things.aggregate([
    {
        $match:{
            _id:1
        }
    },
    {
        $lookup:{
            from:"Users",
            localField:"Users.userId",
            foreignField:"_id",
            as:"usersData"
        }
    },
    {
        $unwind : "$usersData"
    }
])

提前致谢。

【问题讨论】:

  • _id = 1中也有userId : 00002,你能不能显示你的预期结果。
  • _id = 1 中的userId : 00002 没有creator 的角色,但在'users' 数组中spectator,所以他不是预期结果的一部分
  • 用户数组中是否有两个匹配的用途?如果是,那么您想要的结果是在单独的文档中还是在同一文档中。
  • 不可能。每个thing只有一个creator,如果我只有创建者姓名和_id就完美了,但只要我有name就可以了

标签: mongodb aggregation-framework


【解决方案1】:
  • $match事物_id和用户role条件
  • $unwind解构users数组
  • $matchusers角色条件
  • $lookupusers 收藏
  • $arrayElemAt 从查找结果中获取第一个元素
  • $replaceRoot 将上述对象替换为根
db.things.aggregate([
  { $match: { _id: 1, "users.role": "creator" } },
  { $unwind: "$users" },
  { $match: { "users.role": "creator" } },
  {
    $lookup: {
      from: "Users",
      localField: "users.userId",
      foreignField: "_id",
      as: "users"
    }
  },
  {
    $replaceRoot: {
      newRoot: { $arrayElemAt: ["$users", 0] }
    }
  }
])

Playground


不使用$undind 阶段的第二种方法,

  • $match事物_id和用户role条件
  • $filter 迭代 uses 数组的循环并按 role 创建者过滤
  • $arrayElemAt 从上面的过滤结果中选择第一个元素
  • $lookupusers 收藏
  • $arrayElemAt 从查找结果中获取第一个元素
  • $replaceRoot 将上述对象替换为根
db.things.aggregate([
  { $match: { _id: 1, "users.role": "creator" } },
  {
    $addFields: {
      users: {
        $arrayElemAt: [
          {
            $filter: {
              input: "$users",
              cond: { $eq: ["$$this.role", "creator"] }
            }
          },
          0
        ]
      }
    }
  },
  {
    $lookup: {
      from: "Users",
      localField: "users.userId",
      foreignField: "_id",
      as: "users"
    }
  },
  {
    $replaceRoot: {
      newRoot: { $arrayElemAt: ["$users", 0] }
    }
  }
])

Playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2021-07-28
    • 2018-12-11
    • 1970-01-01
    相关资源
    最近更新 更多