【问题标题】:MongoDB $lookup for embedded collections用于嵌入式集合的 MongoDB $lookup
【发布时间】:2020-04-03 00:03:33
【问题描述】:

我有 2 个收藏:

用户集合:

[
   {
      "_id" : ObjectId("3a9ccf7de6348936d88b3601"),
      "first_name" : "John",
   },
   {
       "_id" : ObjectId("3a9ccf7de6348936d88b3602"),
       "first_name" : "Jane",
   }
]

CommentCollection(带有嵌入的ReplyCollection):

[
   {
      "_id" : ObjectId("3a9ccf7de6348936d88b3601"),
      "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
      "body" : "Hello World",
      "replies":
      [
          {
             "_id" : ObjectId("3a9ccf7de6348936d88b3441"),
             "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
             "body" : "World said, Hello Back", 
          }
      ]
   },
   {
       "_id" : ObjectId("3a9ccf7de6348936d88b3602"),
       "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
       "body" : "Hello Stack",
       "replies":
       [
          {
             "_id" : ObjectId("3a9ccf7de6348936d88b3602"),
             "body" : "Stack said Overflow",
             "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
          }
       ]
   }
]

查询加入评论和用户:

db.comments.aggregate([
   { "$lookup": {
     "from": "Users",
     "localField": "user_id",
     "foreignField": "_id",
     "as": "user" } 
   },
   {"$unwind": "$user"}
]);

行为:cmets 和用户表已按预期连接。

问题:是否可以在同一个查询中加入回复用户关系?

提前致谢。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    是的,您可以在 $lookup 中使用 uncorrelated-subquery 来做到这一点:

    db.comments.aggregate([
      {
        $lookup: {
          from: "Users",
          let: {
            repliesUserId: "$replies.user_id",
            userId: "$user_id"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $or: [
                    { $eq: ["$_id", "$$userId"] },
                    { $in: ["$_id", "$$repliesUserId"] }
                  ]
                }
              }
            }
          ],
          as: "user"
        }
      }
    ]);
    

    测试: MongoDB-Playground

    【讨论】:

    • 差不多,结果是一个数组,包含所有发布任何回复的用户,但不包括回复对象内的用户对象
    • @creality:我建议用代码来做,用代码很容易&我试过&它变得越来越复杂&不建议在大型数据集上做..
    • 真的。考虑将回复存储在与 cmets 相同的集合中,而不是作为子文档。这让事情变得容易多了……
    • @creality :不应该每次都这样,如果replies 数组更大,您的文档可能会更大。但总的来说,如果您的 Users 集合只有两个字段 first_name &_id 如上所述,并且您的应用程序可以灵活地每次将 first_name 写入 comments 集合以及安全问题(您可能不想每次检索 cmets 数据时都暴露 first_name)。因此,请检查所有这些并思考我会在当前情况下进行一些小的编码以获得所需的内容(通常,如果数据库无法将其卸载到代码中)
    • 日本这是真的。但是我测试了一些案例,我发现通常在评论文档中存储回复、投票等并不是一个好主意。 Mongo 对每个对象有 16MB 的限制,并且对象增长很快。例如,我添加了 100.000 个赞,瞧 - 增加了 16MB。我想出了拆分结构。
    猜你喜欢
    • 1970-01-01
    • 2021-09-17
    • 2016-02-23
    • 2021-02-22
    • 2023-03-09
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多